Bioinformática Estadística
Bioinformática Estadística
Bioinformática Estadística
Bioinformática Estadística
Análisis estadístico de datos ómicos
2
Copyright ©5 de febrero de 2019
Guillermo Ayala
Guillermo.Ayala@uv.es
This work is free. You can redistribute it and/or modify it under the terms of
the Do What The Fuck You Want To Public License, Version 2, as published by
Sam Hocevar. See http://www.wtfpl.net/ for more details.
ii
Índice general
I Introducción 1
1 Estadística y datos ómicos 3
1.1 Estructura de los datos . . . . . . . . . . . . . . . . . . 3
1.2 Análisis de datos . . . . . . . . . . . . . . . . . . . . . 4
1.3 Sobre herramientas online . . . . . . . . . . . . . . . . 5
1.4 Paquetes transversales . . . . . . . . . . . . . . . . . . 6
1.5 Jerga . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.6 Datos ordenados . . . . . . . . . . . . . . . . . . . . . 6
1.7 Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . 7
2 R y Bioconductor 9
2.1 Sobre R y su instalación . . . . . . . . . . . . . . . . . 9
2.1.1 De cómo instalarlo . . . . . . . . . . . . . . . . 9
2.2 Lo primero con R . . . . . . . . . . . . . . . . . . . . . 10
2.3 Una sola muestra . . . . . . . . . . . . . . . . . . . . . 11
2.3.1 Varias muestras . . . . . . . . . . . . . . . . . . 14
2.4 Datos golub . . . . . . . . . . . . . . . . . . . . . . . . 16
2.5 La función apply . . . . . . . . . . . . . . . . . . . . . 21
2.6 Listas . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.7 Funciones con R . . . . . . . . . . . . . . . . . . . . . 25
2.8 Sobre Bioconductor . . . . . . . . . . . . . . . . . . . . 28
2.9 Paquetes para tami . . . . . . . . . . . . . . . . . . . . 28
3 Anotación 29
3.1 AnnotationDbi . . . . . . . . . . . . . . . . . . . . . . 30
3.2 ChipDb . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.3 OrgDb . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.4 TxDb . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.5 BSgenome . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.6 OrganismDb . . . . . . . . . . . . . . . . . . . . . . . 49
3.7 biomaRt . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.8 KEGGREST . . . . . . . . . . . . . . . . . . . . . . . 51
3.9 Tareas habituales con anotaciones . . . . . . . . . . . 51
3.9.1 Cambiar identificadores de un ExpressionSet . 52
3.10 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . 55
II Datos 57
4 Microarrays 59
4.1 Introducción . . . . . . . . . . . . . . . . . . . . . . . . 59
4.2 Affymetrix GeneChip . . . . . . . . . . . . . . . . . . . 59
4.3 Obteniendo los datos . . . . . . . . . . . . . . . . . . . 60
iii
iv ÍNDICE GENERAL
5 Datos de microarrays 81
5.1 Introducción . . . . . . . . . . . . . . . . . . . . . . . . 81
5.2 sample.ExpressionSet . . . . . . . . . . . . . . . . . . . 81
5.3 Datos golub . . . . . . . . . . . . . . . . . . . . . . . . 83
5.4 Datos ALL . . . . . . . . . . . . . . . . . . . . . . . . 85
5.5 Construyendo un ExpressionSet . . . . . . . . . . . . 86
5.6 Un experimento con levadura . . . . . . . . . . . . . . 92
5.7 De cómo utilizar un ExpressionSet . . . . . . . . . . . 94
5.8 NCBI GEO . . . . . . . . . . . . . . . . . . . . . . . . 96
5.9 GSE21779 . . . . . . . . . . . . . . . . . . . . . . . . 96
5.10 GSE1397 . . . . . . . . . . . . . . . . . . . . . . . . . 97
5.11 Datos GSE20986 . . . . . . . . . . . . . . . . . . . . . 100
5.12 GSE34764 . . . . . . . . . . . . . . . . . . . . . . . . 101
5.13 ArrayExpress . . . . . . . . . . . . . . . . . . . . . . . 102
5.14 Varios . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
5.14.1 Guardando la matriz de expresión . . . . . . . 102
5.15 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . 103
VI Agregación 293
19 Listas de características ordenadas 295
19.1 Estabilidad de la lista ordenada . . . . . . . . . . . . . 296
19.1.1 Diferentes criterios de ordenación . . . . . . . . 296
19.1.2 Estabilidad frente a cambios en los datos . . . 300
19.2 Agregación de listas . . . . . . . . . . . . . . . . . . . 303
21 Probabilidad 321
21.1 Experimento, suceso y probabilidad . . . . . . . . . . . 321
21.1.1 Contando: variaciones, permutaciones y combi-
naciones . . . . . . . . . . . . . . . . . . . . . 326
21.1.2 Un poco de teoría . . . . . . . . . . . . . . . . 329
21.2 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . 330
21.3 Variable aleatoria . . . . . . . . . . . . . . . . . . . . . 331
21.3.1 Variable aleatoria discreta . . . . . . . . . . . . 331
21.3.2 Ejercicios . . . . . . . . . . . . . . . . . . . . . 332
21.3.3 Variable aleatoria continua . . . . . . . . . . . 333
21.3.4 Ejercicios . . . . . . . . . . . . . . . . . . . . . 335
21.3.5 Función de distribución . . . . . . . . . . . . . 335
21.3.6 Función de distribución muestral o empirica . . 336
21.3.7 Ejercicios . . . . . . . . . . . . . . . . . . . . . 336
21.4 Media y varianza . . . . . . . . . . . . . . . . . . . . . 337
ÍNDICE GENERAL ix
23 Estimación 361
23.1 Introducción . . . . . . . . . . . . . . . . . . . . . . . . 361
23.2 La población . . . . . . . . . . . . . . . . . . . . . . . 361
23.3 Estimación puntual . . . . . . . . . . . . . . . . . . . . 362
23.4 Algunas definiciones . . . . . . . . . . . . . . . . . . . 364
23.5 Estimación puntual de la media . . . . . . . . . . . . . 364
23.6 Intervalo de confianza para la media . . . . . . . . . . 364
23.6.1 Asumimos que conocemos la varianza . . . . . 364
23.6.2 No asumimos la varianza conocida . . . . . . . 367
23.7 Error absoluto y tamaño de la muestra . . . . . . . . . 373
23.8 Estimación de la varianza en poblaciones normales . . 376
30 Meta-análisis 477
30.1 Método de Fisher . . . . . . . . . . . . . . . . . . . . . 477
30.2 Método de Stouffer . . . . . . . . . . . . . . . . . . . . 478
31 Miscelánea 479
31.1 Algoritmo bipesado de Tukey de un solo paso . . . . . 479
31.2 Median polish . . . . . . . . . . . . . . . . . . . . . . . 480
31.3 Datos faltantes . . . . . . . . . . . . . . . . . . . . . . 482
31.3.1 Algoritmo de normalización del k-vecino más
próximo . . . . . . . . . . . . . . . . . . . . . . 482
31.4 Datos multimodales . . . . . . . . . . . . . . . . . . . 483
31.4.1 TCGA . . . . . . . . . . . . . . . . . . . . . . . 483
Glosario 523
xii ÍNDICE GENERAL
Prólogo
xiii
xiv ÍNDICE GENERAL
9. Fraude.
Con el análisis estadístico de los datos tienen que ver los puntos 3, 6,
7 y 8. Hay que hacer bien las cosas. Y desde el principio.
En muchas ocasiones biólogos o médicos o biotecnólogos o bioquí-
micos o . . . me han indicado que querían aprender más de Probabili-
dad y Estadística. Normalmente después de que les has analizado unos
datos para una tesis o un artículo. Al principio, con interés, les reco-
miendas algún texto esperando que les ayude. El final de la historia
suele ser el mismo. Que no leen nunca el libro. Aprender Estadística
es muy fácil. Se coge un libro sencillo. El libro lleva una página que
pone el número uno. Se lee esa página. Se le da la vuelta y se lee la
Es una opinión poco siguiente numerada con el 2. Y así sucesivamente. Y no hay otra.
compartida.
datos sin procesado previo. Los usamos por haber sido analizados en
otros textos o en ejemplos de R/Bioconductor o, simplemente, porque
son bonitos de estudiar.
Es de destacar que recientemente Nature Genetics ha refrendado
el uso de Bioconductor.
Introducción
1
Capítulo 1
Estadística y datos
ómicos
fortunes::fortune(50)
##
## To paraphrase provocatively, 'machine learning is
## statistics minus any checking of models and
## assumptions'.
## -- Brian D. Ripley (about the difference
## between machine learning and statistics)
## useR! 2004, Vienna (May 2004)
3
4 CAPÍTULO 1. ESTADÍSTICA Y DATOS ÓMICOS
DAVID http://david.abcc.ncifcrf.gov.
g:Profiler http://biit.cs.ut.ee/gprofiler/.
Gitools http://www.gitools.org.
1.5 Jerga
En un campo como es la Bioinformática un problema mayor es el
lenguaje que se utiliza. Un texto de Estadística o un texto de Genética
32
Sin ser peyorativo, campos tiene una jerga consolidada. Son campos de trabajo maduros.32 Prác-
de investigación viejos. ticamente cada campo de investigación va desarrollando una jerga33
33
Mejor una jerigonza. en donde suele haber una parte interesada. Impedir el acceso a los que
no son de este campo. Aquí el problema es grave porque se mezclan
jergas al mismo tiempo que se desarrolla una nueva. Para intentar evi-
tar esta barrera he incluido un glosario al final del texto que intenta
aclarar los términos y sirva de referencia rápida. Sin embargo, quizás
la mayor dificultad de esta disciplina sea este, entender la jerga de los
34
En mi caso de los biólogos. demás.34
A los informáticos los entien-
do. Hablan menos de hecho.
1.6 Datos ordenados
Un problema que comparte el análisis de datos ómicos con cual-
quier otro problema de análisis de datos es tener unos datos de entra-
35
Tidy data. da ordenados35 así como unas salidas de las distintas funciones que
los analizan que sean ordenadas, fácilmente interpretables y que pue-
dan ser una entrada ordenada para un procedimiento posterior. El
término utilizado en [150] es tidy data. En este texto utilizaremos
distintas herramientas que prestan atención a este aspecto del aná-
lisis que ahorra mucho tiempo de trabajo y muchísimos quebraderos
de cabeza. Entre otros paquetes utilizaremos [13, biobroom] y [119,
broom].
1.7. BIBLIOGRAFÍA 7
1.7 Bibliografía
A lo largo del manual se presta mucha atención a citar con pre-
cisión las referencias originales del material. La comprensión pre-
cisa de las técnicas supone la consulta de la referencia original.36 36
Hay una peligrosa ten-
Un libro que trata cómo hacer las cosas con R/Bioconductor pe- dencia a creer que leyendo
ro no lo que se hace o porqué se hace es [127]. Es una guía de uso un resumen se conoce la téc-
muy bien elaborada. Un texto con un objetivo similar al nuestro es nica. No es cierto. Las re-
[63]. Un manual online que sigue una línea muy similar a este es ferencias bibliográficas siem-
http://genomicsclass.github.io/book/. pre hay que consultarlas.
8 CAPÍTULO 1. ESTADÍSTICA Y DATOS ÓMICOS
Capítulo 2
R y Bioconductor
install.packages(``UsingR'')
1 Dios nos perdone por usar esta palabra aunque no creo que lo haga.
9
10 CAPÍTULO 2. R Y BIOCONDUCTOR
library(UsingR)
help.start()
?hist
O simplemente,
2 Una
buena idea es imprimirla y tenerla a mano.
3 Es
la opción más educativa en donde aprendemos realmente a trabajar con el
programa.
2.3. UNA SOLA MUESTRA 11
help(hist)
## [1] 3 6 3 6 7 1 4 7 4 4
x = c(3,6,3,6,7,1,4,7,4,4)
class(x)
## [1] "numeric"
## [1] 3 6 3 6 7 1 4 7 4 4
x[1]
## [1] 3
x[7]
## [1] 4
Podemos ver los datos que están entre el 3 y el 7. Para ello fijé-
monos en el siguiente código.
3:7
## [1] 3 4 5 6 7
seq(3,7,1)
## [1] 3 4 5 6 7
x[3:7]
## [1] 3 6 7 1 4
Podemos tener interés en saber los valores de los datos que ocupan
las posiciones 1, 3 y de la 5 a la 8. Estas posiciones las podemos obtener
con
c(1,3,5:8)
## [1] 1 3 5 6 7 8
x[c(1,3,5:8)]
## [1] 3 3 7 1 4 7
Puede que nuestro interés en ver los datos no venga dado por la
posición que ocupan sino por su valor. Por ejemplo, queremos saber
cuántos de estos datos superan o son iguales a 4. ¿Cómo lo hacemos?
Lo lógico es comparar los valores de x con 4. Lo hacemos con
x >= 4
x[x >= 4]
## [1] 6 6 7 4 7 4 4
Nos devuelve los datos que ocupan las posiciones donde se daba la
condición, donde la condición era cierta. Podemos saber qué valores
toman los datos que son mayores que 37 con
x[x > 6]
## [1] 7 7
o bien los datos que son mayores que 4 y menores o iguales que 6.
## [1] 6 6
## [1] 6 6
## [1] 3 3 7 1 4 7 4 4
x[x == 4]
## [1] 4 4 4
which(x == 4)
## [1] 7 9 10
39 39
El resto de operadores ló-
gicos los encontramos en la
De cómo ordenar un vector Supongamos que queremos ordenar ayuda de Logical Operators:
el vector x. & (&&) corresponde con la
intersección, | (||) correspon-
sort(x) de con la unión y la negación
de una condición la obtene-
## [1] 1 3 3 4 4 4 6 6 7 7 mos con !.
Nos devuelve los valores ordenados. Sin embargo, con frecuencia
necesitamos saber la posición que ocupaban en el vector original estos
valores.
sort(x,index.return = TRUE)
## $x
## [1] 1 3 3 4 4 4 6 6 7 7
##
## $ix
## [1] 6 1 3 7 9 10 2 4 5 8
## $x
## [1] 7 7 6 6 4 4 4 3 3 1
##
## $ix
## [1] 5 8 2 4 7 9 10 1 3 6
14 CAPÍTULO 2. R Y BIOCONDUCTOR
40
Estamos generando valo- * Ej. 2 — Ejecutad el siguiente código.40
res con distribución normal x = rnorm(23489,mean=45,sd=2.3)
con media 45 y desviación es-
tándar 2.3. Simplemente son Se pide:
unos datos para trabajar con 1.¿Cuántos valores de x son mayores o iguales de 39.4?
ellos.
2.¿Cuántos valores de x son estrictamente menores que 46?
3.¿Cuántos valores de x son estrictamente menores que 46 y ma-
yores o iguales de 39.4?
4.¿Cuántos valores son tales que su parte entera (por defecto) es
igual a 40? Se puede utilizar también la función base::floor.
set.seed(123)
(x = matrix(rpois(10*4,lambda=5),nrow=10))
class(x)
## [1] "matrix"
colnames(x) = c("sample1","sample2","sample3","sample4")
41 41
El siguiente código es equivalente al anterior y más simple. La función base::c simple-
mente construye un vector
colnames(x) = paste0("sample",1:4) y en cada posición tiene el
nombre de la muestra. Pode-
Además sabemos que en cada fila tenemos la expresión correspon- mos concatenar también nú-
diente a un gen distinto. De momento, supondremos que son “gene1”, meros.
“gene2”, etc. Vamos a cambiarle el nombre las filas utilizando el código
que acabamos de ver.
rownames(x) = paste0("gene",1:10)
x[6,2]
## [1] 8
o bien con
x["gene6","sample2"]
## [1] 8
x[,2]
x[,"sample2"]
data(golub,package = "multtest")
golub.cl
## [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
## [24] 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1
class(golub.cl)
## [1] "numeric"
## [1] ALL ALL ALL ALL ALL ALL ALL ALL ALL ALL ALL
## [12] ALL ALL ALL ALL ALL ALL ALL ALL ALL ALL ALL
## [23] ALL ALL ALL ALL ALL AML AML AML AML AML AML
## [34] AML AML AML AML AML
## Levels: ALL AML
table(golub.fac)
## golub.fac
## ALL AML
## 27 11
summary(golub.fac)
## ALL AML
## 27 11
pacman::p_load(ggplot2)
df0 = data.frame(golub.fac)
png(paste0(dirTamiFigures,"RBio39.png"))
ggplot(df0,aes(x=golub.fac))+geom_bar()
dev.off()
class(golub)
## [1] "matrix"
nrow(golub)
## [1] 3051
ncol(golub)
## [1] 38
dim(golub)
## [1] 3051 38
## [1] 0.19595
44 44
Estos datos han sido Y todos los niveles de este gen lo tendremos con
preprocesados partiendo de
los datos originales. Pueden golub[2000,]
aparecer valores negativos.
En § 5.3 se explica y se en- ## [1] 0.73124 -0.19598 0.51981 -0.54371 0.55596
tiende el porqué del valor ne- ## [6] 1.40683 0.79772 0.59493 0.99503 0.39529
gativo. Lo importante valor ## [11] 0.09834 0.19595 0.85017 -1.39979 1.09789
menor indica menor expre- ## [16] -0.74362 0.44207 0.27698 -0.04128 -1.60767
sión, valor mayor indica ma- ## [21] -1.06221 -1.12665 0.47863 -0.44014 0.22286
yor expresión. ## [26] 0.42795 0.65427 0.07257 -0.28093 -0.20985
## [31] 0.05160 -1.44434 -0.17118 -1.34158 0.92325
## [36] -0.21462 -1.34579 1.17048
45
Expression profile. Estos valores reciben el nombre de perfil de expresión.45 Podemos
representar el perfil de expresión (figura 2.2). Definimos qué van en el
eje de abscisas y en el eje de ordenadas.
pacman::p_load(ggplot2)
muestra = 1:ncol(golub) ## En abscisas el número de la muestra
y2000 = golub[2000,] ## En ordenadas su expresión
df = data.frame(muestra = 1:ncol(golub),y2000= golub[2000,])
png(paste0(dirTamiFigures,"RBio47.png"))
ggplot(df,aes(x = muestra,y= y2000))+geom_point()
dev.off()
2.4. DATOS GOLUB 19
golub[2000,golub.fac == "AML"]
Figura 2.2: (a) Perfil de expresión del gen en la fila 2000. (b) Perfil de expresión del gen en fila 2000 diferenciando el tipo
de leucemia. (c) Perfil de expresión del gen en fila 2000 diferenciando el tipo de leucemia mediante un color distinto.
Utilizamos distintos dibujos (facets) alineados en vertical. (d) Perfil de expresión del gen en fila 2000 diferenciando el
tipo de leucemia mediante un color distinto. Utilizamos distintos dibujos (facets) alineados en vertical.
golub.gnames[2000,]
class(golub.gnames)
## [1] "matrix"
dim(golub.gnames)
## [1] 3051 3
Cada fila nos da información con el gen del cual tenemos su perfil
de expresión en la matriz golub. En concreto, ¿qué tenemos en la fila
2000?
golub.gnames[2000,]
golub.gnames[2000,2]
golub.gnames[2000,3]
## [1] "X74794_at"
2.5. LA FUNCIÓN APPLY 21
rownames(golub) = golub.gnames[,3]
colnames(golub) = golub.fac
mean(golub[2000,])
## [1] 0.02080211
median(golub[2000,])
## [1] 0.147145
Figura 2.3: Medias en muestras AML frente a medias en muestras ALL para datos multtest::golub. En (a) tenemos
los puntos tal cual y en (b) utilizamos un sombreado. (c) Medianas en muestras AML frente a medianas en muestras
ALL para datos multtest::golub. sustituimos la media por la mediana.
geneset1 = c(1,4)
geneset2 = c(2,5,7,8)
geneset3 = c(1,5,6)
(genesets = vector("list",3))
## [[1]]
## NULL
##
## [[2]]
## NULL
##
## [[3]]
## NULL
genesets[[1]] = geneset1
genesets[[2]] = geneset2
genesets[[3]] = geneset3
genesets
## [[1]]
## [1] 1 4
##
## [[2]]
## [1] 2 5 7 8
##
## [[3]]
## [1] 1 5 6
names(genesets) = paste0("set",1:3)
genenames = paste0("gene",1:10)
genesets[[1]] = genenames[geneset1]
genesets[[2]] = genenames[geneset2]
genesets[[3]] = genenames[geneset3]
MediaDesviacion = function(x){
resultado = c(mean(x),sd(x))
resultado
}
53
También podemos usar re- La función devuelve lo que tiene en la última línea.53 Una vez le
turn. declaramos la función podemos usarla.54 La aplicamos a datos gene-
54
Copiamos y pegamos en lí- rados con distribución normal.
nea de comandos.
x = rnorm(23,mean=12,sd=1.3)
MediaDesviacion(x)
Y la utilizamos.
MediaDesviacionPercentil(x)
MediaDesviacionPercentil(x,ordenpercentil=.7)
y = matrix(1:16,ncol=4)
is.vector(y)
## [1] FALSE
MediaDesviacionPercentilError(y)
Y la probamos.
MediaDesviacionPercentilErrorLista(x)
## $media
## [1] 13.31447
##
## $de
## [1] 0.8567743
x.des = MediaDesviacionPercentilErrorLista(x)
x.des$media
## [1] 13.31447
x.des$de
## [1] 0.8567743
** Ej. 9 — Dado un vector x programar una función que nos de-
vuelva en una lista la media y la varianza del vector. Los elementos
de la lista se han de llamar media y varianza.
28 CAPÍTULO 2. R Y BIOCONDUCTOR
source("http://www.bioconductor.org/biocLite.R")
biocLite()
source("http://www.bioconductor.org/biocLite.R")
biocLite("ALL")
chooseBioCmirror()
setRepositories()
55 55
Tarda un tiempo y se reco- • Una instalación completa se tiene con
mienda una buena conexión
a Internet. TIPO = TODO; source("http://www.uv.es/docencia/tami/AllTami.R")
Capítulo 3
Anotación
3.1 AnnotationDbi
Las bases de datos de tipo ChipDb, OrgDb y TxDb heredan to-
dos los métodos de la clase AnnotationDb que está definida en [109,
AnnotationDbi]. Por ello los métodos aplicables a AnnotationDb son
aplicables a las demás: columns, keytypes, keys y select. Con es-
tos métodos podremos extraer información de las bases de las datos
(objetos de clase ChipDb, OrgDb y TxDb) correspondientes. Previo al
uso de las distintas bases de datos de anotación es pues conveniente
conocer los objetos AnnotationDb.
pacman::p_load("AnnotationDbi")
pacman::p_load("hgu133a.db")
ls("package:hgu133a.db")
hgu133a.db
## ChipDb object:
## | DBSCHEMAVERSION: 2.1
## | Db type: ChipDb
## | Supporting package: AnnotationDbi
## | DBSCHEMA: HUMANCHIP_DB
## | ORGANISM: Homo sapiens
## | SPECIES: Human
3.1. ANNOTATIONDBI 31
## | MANUFACTURER: Affymetrix
## | CHIPNAME: Human Genome U133 Set
## | MANUFACTURERURL: http://www.affymetrix.com/support/technical/byproduct.affx?product
## | EGSOURCEDATE: 2015-Sep27
## | EGSOURCENAME: Entrez Gene
## | EGSOURCEURL: ftp://ftp.ncbi.nlm.nih.gov/gene/DATA
## | CENTRALID: ENTREZID
## | TAXID: 9606
## | GOSOURCENAME: Gene Ontology
## | GOSOURCEURL: ftp://ftp.geneontology.org/pub/go/godatabase/archive/latest-lite/
## | GOSOURCEDATE: 20150919
## | GOEGSOURCEDATE: 2015-Sep27
## | GOEGSOURCENAME: Entrez Gene
## | GOEGSOURCEURL: ftp://ftp.ncbi.nlm.nih.gov/gene/DATA
## | KEGGSOURCENAME: KEGG GENOME
## | KEGGSOURCEURL: ftp://ftp.genome.jp/pub/kegg/genomes
## | KEGGSOURCEDATE: 2011-Mar15
## | GPSOURCENAME: UCSC Genome Bioinformatics (Homo sapiens)
## | GPSOURCEURL: ftp://hgdownload.cse.ucsc.edu/goldenPath/hg19
## | GPSOURCEDATE: 2010-Mar22
## | ENSOURCEDATE: 2015-Jul16
## | ENSOURCENAME: Ensembl
## | ENSOURCEURL: ftp://ftp.ensembl.org/pub/current_fasta
## | UPSOURCENAME: Uniprot
## | UPSOURCEURL: http://www.uniprot.org/
## | UPSOURCEDATE: Thu Oct 1 23:31:58 2015
columns(hgu133a.db)
No todas las variables que hemos obtenido con columns son utili-
zables para realizar consultas. Aquellas utilizables para las consultas
las podemos conocer con keytypes. A estas variables las llamamos
llaves (keys).
32 CAPÍTULO 3. ANOTACIÓN
keytypes(hgu133a.db)
head(keys(hgu133a.db,keytype="ENTREZID"))
head(keys(hgu133a.db,keytype="ENSEMBL"))
AnnotationDbi::select(hgu133a.db,keys=ids,
columns=c("ENTREZID","ENSEMBL","SYMBOL"),
keytype="PROBEID")
3.2 ChipDb
Si trabajamos con microarrays (§ 4) nuestras características serán
62
Asociadas a genes. las sondas.62 Estas sondas tendrán un identificador que el fabricante
del chip le ha asignado. Esto no es informativo para nosotros. Hemos
3.2. CHIPDB 33
pacman::p_load(hgu133a.db)
mappedProbes = mappedkeys(hgu133aENTREZID)
mappedProbesList = as.list(hgu133aENTREZID[mappedProbes])
## $`1053_at`
## [1] "5982"
mappedProbesList[4567]
## $`205255_x_at`
## [1] "6932"
Si hacemos
ls("package:hgu133a.db")
pacman::p_load("hgu95av2.db")
columns(hgu95av2.db)
keytypes(hgu95av2.db)
Los identificadores que teníamos eran los AffyID, esto es, los iden-
tificadores de las sondas utilizadas o PROBEID. Podemos plantearnos
su correspondencia con el símbolo o nombre del gen y las proteínas
asociadas en la base de datos PFAM.
columns = c("PFAM","SYMBOL")
AnnotationDbi::select(hgu95av2.db, keys=ids, columns, keytype="PROBEID")
3.3 OrgDb
Este tipo de paquete se refiere a un organismo dado y está centrado
en el gen. Veamos como ejemplo el relativo a ser humano.
pacman::p_load(org.Hs.eg.db)
columns(org.Hs.eg.db)
O bien con
keytypes(org.Hs.eg.db)
head(keys(org.Hs.eg.db, keytype="ENTREZID"))
head(keys(org.Hs.eg.db, keytype="ENSEMBL"))
Y en Gene Ontology.
head(keys(org.Hs.eg.db, keytype="GO"))
AnnotationDbi::select(org.Hs.eg.db,keys=ids,column="SYMBOL",keytype='ENTREZID')
## ENTREZID SYMBOL
## 1 1 A1BG
## 2 2 A2M
## 3 3 A2MP1
## 4 9 NAT1
## 5 10 NAT2
(id = "ENSG00000171428")
## [1] "ENSG00000171428"
res[,"GO"]
pacman::p_load(GO.db)
3.4 TxDb
Los paquetes TxDb están centrados en el genoma. Vamos a traba-
66
https://en.wikipedia. jar con la mosca de la drosophila melanogaster.66 Cargamos la base
org/wiki/Drosophila_ de datos.
melanogaster.
3.4. TXDB 37
library("GenomicFeatures")
library("TxDb.Dmelanogaster.UCSC.dm3.ensGene")
## [1] "TxDb"
## attr(,"package")
## [1] "GenomicFeatures"
txdb = TxDb.Dmelanogaster.UCSC.dm3.ensGene
class(txdb)
## [1] "TxDb"
## attr(,"package")
## [1] "GenomicFeatures"
txdb
## TxDb object:
## # Db type: TxDb
## # Supporting package: GenomicFeatures
## # Data source: UCSC
## # Genome: dm3
## # Organism: Drosophila melanogaster
## # Taxonomy ID: 7227
## # UCSC Table: ensGene
## # Resource URL: http://genome.ucsc.edu/
## # Type of Gene ID: Ensembl gene ID
## # Full dataset: yes
## # miRBase build ID: NA
## # transcript_nrow: 29173
## # exon_nrow: 76920
## # cds_nrow: 62135
## # Db created by: GenomicFeatures package from Bioconductor
## # Creation time: 2015-10-07 18:15:53 +0000 (Wed, 07 Oct 2015)
## # GenomicFeatures version at creation time: 1.21.30
## # RSQLite version at creation time: 1.0.0
## # DBSCHEMAVERSION: 1.1
columns(txdb)
38 CAPÍTULO 3. ANOTACIÓN
y con
keytypes(txdb)
pacman::p_load(GenomicFeatures)
68
En http: Por ejemplo: ¿Qué cromosomas tenemos?68
//ucscbrowser.
genenetwork.org/ seqlevels(txdb)
cgi-bin/hgGateway?
hgsid=732&clade=insect& ## [1] "chr2L" "chr2R" "chr3L"
org=0&db=0 podemos en- ## [4] "chr3R" "chr4" "chrX"
contrar una explicación ## [7] "chrU" "chrM" "chr2LHet"
detallada. ## [10] "chr2RHet" "chr3LHet" "chr3RHet"
## [13] "chrXHet" "chrYHet" "chrUextra"
seqlevels(txdb) = "chr2L"
(txdb.tr = transcripts(txdb))
txdb.tr[c(1:3,1000)]
(txdb.ex = exons(txdb))
txdb.ex[123]
(txdb.cds = cds(txdb))
length(txdb.cds)
## [1] 11003
70
En la salida que sigue nos Podemos ver la hebra en la que están70
hace una tabla de frecuen-
cias. strand(txdb.cds)
transcriptsBy(txdb, by="gene")
exonsBy(txdb, by="gene")
## [2] <NA>
## [3] <NA>
## [4] <NA>
## [5] <NA>
## [6] <NA>
##
## $FBgn0000053
## GRanges object with 8 ranges and 2 metadata columns:
## seqnames ranges strand | exon_id
## [1] chr2L 7014861-7016374 - | 9389
## [2] chr2L 7016437-7017486 - | 9390
## [3] chr2L 7017545-7017966 - | 9391
## [4] chr2L 7018085-7018374 - | 9392
## [5] chr2L 7018149-7018374 - | 9393
## [6] chr2L 7018431-7019080 - | 9394
## [7] chr2L 7019135-7019382 - | 9395
## [8] chr2L 7023529-7023940 - | 9396
## exon_name
## [1] <NA>
## [2] <NA>
## [3] <NA>
## [4] <NA>
## [5] <NA>
## [6] <NA>
## [7] <NA>
## [8] <NA>
##
## ...
## <2983 more elements>
## -------
## seqinfo: 1 sequence from dm3 genome
cdsBy(txdb, by="tx")
## exon_rank
## [1] 1
## [2] 2
## [3] 3
##
## $3
## GRanges object with 2 ranges and 3 metadata columns:
## seqnames ranges strand | cds_id cds_name
## [1] chr2L 7680-8116 + | 1 <NA>
## [2] chr2L 8229-8610 + | 4 <NA>
## exon_rank
## [1] 1
## [2] 2
##
## ...
## <4948 more elements>
## -------
## seqinfo: 1 sequence from dm3 genome
intronsByTranscript(txdb)
fiveUTRsByTranscript(txdb)
threeUTRsByTranscript(txdb)
3.5 BSgenome
Estos paquetes contienen datos de secuencias para organismos se-
cuenciados.
BSgenome.Dmelanogaster.UCSC.dm3
pacman::p_load(BSgenome.Dmelanogaster.UCSC.dm3)
tx2seqs = extractTranscriptSeqs(BSgenome.Dmelanogaster.UCSC.dm3,TxDb.Dmelanogaster.UCSC.
tx2seqs[[1]]
tx2seqs[[1]][1000:1020]
suppressWarnings(translate(tx2seqs[[1]]))
suppressWarnings(translate(tx2seqs))
cds2seqs = extractTranscriptSeqs(BSgenome.Dmelanogaster.UCSC.dm3,
cdsBy(txdb, by="tx"))
translate(cds2seqs)
BSgenome.Hsapiens.UCSC.hg19
Estos paquetes contienen datos de secuencias para organismos se-
cuenciados.
48 CAPÍTULO 3. ANOTACIÓN
pacman::p_load(BSgenome.Hsapiens.UCSC.hg19)
Hsapiens
## Human genome:
## # organism: Homo sapiens (Human)
## # provider: UCSC
## # provider version: hg19
## # release date: Feb. 2009
## # release name: Genome Reference Consortium GRCh37
## # 93 sequences:
## # chr1 chr2
## # chr3 chr4
## # chr5 chr6
## # chr7 chr8
## # chr9 chr10
## # ... ...
## # chrUn_gl000241 chrUn_gl000242
## # chrUn_gl000243 chrUn_gl000244
## # chrUn_gl000245 chrUn_gl000246
## # chrUn_gl000247 chrUn_gl000248
## # chrUn_gl000249
## # (use 'seqnames()' to see all the sequence names,
## # use the '$' or '[[' operator to access a given
## # sequence)
seqNms = seqnames(Hsapiens)
head(seqNms)
getSeq(Hsapiens, seqNms[1:2])
3.6 OrganismDb
Un paquete de tipo OrganismDb nos permite combinar informa-
ción (para el organismo con que estemos trabajando) de GO.db con
el correspondiente TxDb y OrgDb.72 72
Buscar OrganismDb en
Bioconductor.
pacman::p_load(Homo.sapiens)
transcripts(Homo.sapiens, columns=c("TXNAME","SYMBOL"))
3.7 biomaRt
El paquete [42, biomaRt] es un interfaz para poder acceder a una
73
http://www.biomart. serie de bases de datos que implementan BioMart.73
org.
pacman::p_load(biomaRt)
listMarts(host="www.ensembl.org")
## biomart version
## 1 ENSEMBL_MART_ENSEMBL Ensembl Genes 95
## 2 ENSEMBL_MART_MOUSE Mouse strains 95
## 3 ENSEMBL_MART_SNP Ensembl Variation 95
## 4 ENSEMBL_MART_FUNCGEN Ensembl Regulation 95
(ensembl = useMart("ENSEMBL_MART_ENSEMBL",host="www.ensembl.org"))
head(listDatasets(ensembl))
## dataset
## 1 acalliptera_gene_ensembl
## 2 acarolinensis_gene_ensembl
## 3 acitrinellus_gene_ensembl
## 4 amelanoleuca_gene_ensembl
## 5 amexicanus_gene_ensembl
## 6 anancymaae_gene_ensembl
## description
3.8. KEGGREST 51
(ensembl = useMart("ENSEMBL_MART_ENSEMBL",dataset="hsapiens_gene_ensembl",
host="www.ensembl.org"))
head(listAttributes(ensembl))
De hecho, son
nrow(listAttributes(ensembl))
Podemos comprobar que hay muchos que identifican el gen con las
sondas de Affymetrix, en concreto, con los AffyID. Supongamos que
nos fijamos en los siguientes AffyID.
affyids=c("202763_at","209310_s_at","207500_at")
getBM(attributes=c('affy_hg_u133_plus_2', 'entrezgene'),
filters = 'affy_hg_u133_plus_2',
values = affyids, mart = ensembl)
3.8 KEGGREST
Con [135, KEGGREST] podemos acceder a la base de datos KEGG.
En concreto permite el acceso a KEGG REST API.
pacman::p_load("Biobase","AnnotationDbi","BiocGenerics")
data(gse1397,package="tamidata")
Biobase::annotation(gse1397)
## [1] "hgu133a"
75
En https://www. Lo cargamos.75
bioconductor.org/
packages/3.3/data/ pacman::p_load("hgu133a.db")
annotation/ tenemos el
listado de los paquetes de Como hemos visto en § 3.1 con AnnotationDbi::columns podemos
anotación de los que dispone ver la información que tenemos y con AnnotationDbi::keytypes las
Bioconductor. llaves con las que podemos realizar consultas.
columns(hgu133a.db)
keytypes(hgu133a.db)
Vemos que, en este caso coinciden columns y keys. Los valores los
tenemos con
3.9. TAREAS HABITUALES CON ANOTACIONES 53
head(keys(hgu133a.db,keytype="PROBEID"))
head(featureNames(gse1397))
¿Coinciden todos?
table(featureNames(gse1397) == keys(hgu133a.db,keytype="PROBEID"))
##
## FALSE TRUE
## 53 22230
head(featureNames(gse1397)[control])
## [1] "AFFX-hum_alu_at"
## [2] "AFFX-HUMGAPDH/M33197_3_at"
## [3] "AFFX-HUMGAPDH/M33197_5_at"
## [4] "AFFX-HUMGAPDH/M33197_M_at"
## [5] "AFFX-HUMISGF3A/M97935_3_at"
## [6] "AFFX-HUMISGF3A/M97935_5_at"
probeid2entrez =
AnnotationDbi::select(hgu133a.db,keys=featureNames(gse1397),
columns="ENTREZID",keytype="PROBEID")
54 CAPÍTULO 3. ANOTACIÓN
class(probeid2entrez)
## [1] "data.frame"
head(probeid2entrez)
## PROBEID ENTREZID
## 1 1007_s_at 780
## 2 1007_s_at 100616237
## 3 1053_at 5982
## 4 117_at 3310
## 5 121_at 7849
## 6 1255_g_at 2978
indices = match(featureNames(gse1397),probeid2entrez$PROBEID)
¿Cómo se ha resuelto?
head(featureNames(gse1397))
head(probeid2entrez$PROBEID,n=7)
head(indices)
## [1] 1 3 4 5 6 7
eset = gse1397
fData(eset) = probeid2entrez[indices,]
all.equal(fData(eset)$PROBEID,featureNames(eset))
## [1] TRUE
3.10. EJERCICIOS 55
3.10 Ejercicios
* Ej. 12 — Determinar los códigos Entrez, Gene Ontology y En-
sembl para los genes BRCA1 y BRCA2 implicados en el cáncer de
mama.
* Ej. 13 — Se pide encontrar el gen BRCA1 en el ratón (Mus mus-
culus). Utilizad el paquete de anotación [29, org.Mm.eg.db].
56 CAPÍTULO 3. ANOTACIÓN
Parte II
Datos
57
Capítulo 4
Microarrays
4.1 Introducción
En este tema tratamos sobre datos de expresión obtenidos utili-
zando microarrays. Nos ocupamos del procesado (o mejor, del pre-
procesado) de los datos desde los datos originales (o datos a nivel de
sonda) hasta los datos tal y como los hemos estado analizando.
Los datos multtest::golub que hemos usado ya han sido preproce-
sados. En este tema nos ocupamos de este punto previo y no menor.
Muchos de los análisis de expresión diferencial posterior dependen de
un modo esencial de lo que hacemos antes. Con frecuencia el experi-
mentador confía en el preprocesado que el fabricante del chip realiza.
No necesariamente este preprocesado tiene porqué estar mal hecho
pero en cualquier caso es preciso conocerlo y evaluarlo. En lo que si-
gue veremos como hay funciones que reproducen lo que el fabricante
hace.
En este capítulo la referencia de mayor interés es [58]. En particular
tienen un interés especial los tres primeros capítulos.
La expresión de un gen es el proceso mediante el que se transcribe
el DNA en una serie de copias de mRNA. Los microarrays miden la
cantidad de mRNA para cada gen. El valor de la expresión de un gen
es una medida de luminiscencia relacionada con el mRNA presente.
Esto es para un chip de DNA.
59
60 CAPÍTULO 4. MICROARRAYS
pacman::p_load(Biobase,affy)
annotation(gse21779raw)
## [1] "hgu133plus2"
dim(exprs(gse21779raw))
## [1] 1354896 18
1 Cuando leamos datos veremos que si no tenemos cargado el fichero CDF ne-
png(paste0(dirTamiFigures,"microarray4"))
image(gse21779raw[,1])
dev.off()
## pdf
## 2
probeNames(gse21779raw)
Figura 4.1: Imagen a niveles de
Nos fijamos en la sonda que aparece en la posición 400. gris correspondiente al primer
array de los datos gse21779.
ID = probeNames(gse21779raw)[400]
sum(probeNames(gse21779raw) == ID)
## [1] 11
counts = table(probeNames(gse21779raw))
table(counts)
## counts
## 8 9 10 11 13 14 15 16
## 5 1 6 54130 4 4 2 482
## 20 69
## 40 1
indexProbes(gse21779raw,"both",ID)[[1]]
(posiciones = indexProbes(gse21779raw,"pm",ID)[[1]])
indexProbes(gse21779raw,"mm",ID)[[1]]
library(ggplot2)
pmID = probes(gse21779raw[,1],"pm",ID)
df1 = data.frame(sondas = 1:11,intensidad = pmID[,"GSM542488.CEL.gz"])
ggplot(df1,aes(x=sondas,y=intensidad))+geom_line()
png(paste(dirTamiFigures,"gse217791arrays.png",sep=""))
pm0 = probes(gse21779raw,"pm",ID)
pm0 = data.frame(pm0,sondas=1:11)
pm1 = reshape::melt(pm0,id="sondas")
ggplot2::ggplot(data=pm1,aes(x=sondas,y=value,colour=variable))+
geom_line()+ylab("Intensidad")
dev.off()
(a) (b)
(c) (d)
library(reshape)
pmm = data.frame(sondas=1:11,pm = probes(gse21779raw[,1],"pm",ID),
mm = probes(gse21779raw[,1],"mm",ID))
df2 = reshape::melt(pmm,id="sondas")
levels(df2[,"variable"]) = c("pm","mm")
ggplot(df2,aes(x=sondas,y=value,colour=variable,linetype=variable))
+geom_line()
Podemos hacer una valoración global para todos los arrays que
tenemos. ¿Qué proporción de sondas son tales que el valor PM es
menor que el correspondiente valor MM?
##
## FALSE TRUE
## 4460757 6415887
4.6.2 MA plots
Estos dibujos sirven para determinar si alguno de los microarrays
debe de ser descartado del estudio y si necesitamos homogeneizar
los valores para las distintas muestras. Son una aplicación del dibujo
media-diferencia propuesto por Tukey.80 80
Es conveniente consul-
Trabajamos, en lugar de con las intensidades originales observadas, tar http://en.wikipedia.
con su logaritmo en base 2. Supongamos que ui y vi denotan las org/wiki/MA_plot.
intensidades originales en la sonda i-ésima. Consideramos xi = log2 ui
e yi = log2 vi y estos son los valores a comparar. En este contexto se
habla de dibujos MA ya que
ui
mi = xi − yi = log2 ,
vi
y
1 1 √
ai = (xi + yi ) = log2 ui vi = log2 ui vi .
2 2
Una primera opción es comparar todos los pares de microarrays utili-
zando el dibujo media-diferencia de Tukey.
Una segunda opción consiste en considerar una especie de micro-
array típico y comparar los demás con este. Por ejemplo, una opción
que implementa el paquete [74, affy] en la función affy::MAplot con-
siste en calcular para cada sonda la mediana a lo largo de todos los
microarrays que componen nuestro experimento. Por tanto, la media-
na de las intensidades será xi y el valor yi corresponde a cada uno de
los microarrays de nuestro experimento.
MAplot(gse21779raw[,1:2],pairs=TRUE,plot.method="smoothScatter")
66 CAPÍTULO 4. MICROARRAYS
Figura 4.4: a)Estimador kernel de la densidad de las expresiones a nivel de sonda en el primer microarray. b) Esti-
madores kernel de la densidad de las intensidades para los distintos microarrays. Vemos que hay diferencias claras. c)
Diagramas de cajas de las expresiones a nivel de sonda para los datos gse21779.
affy::hist(gse21779raw[,1])
affy::hist(gse21779raw)
affy::boxplot(gse21779raw)
En este caso los genes con una alta (anormalmente grande) expre-
sión corresponden con el bigote superior en los diagramas de caja que
acabamos de representar.
2 Una mala elección de nombre.
68 CAPÍTULO 4. MICROARRAYS
apply(probes(gse21779raw,"pm"),2,min)
## GSM542488.CEL.gz GSM542555.CEL.gz
## 32 31
## GSM542556.CEL.gz GSM542557.CEL.gz
## 34 33
## GSM542558.CEL.gz GSM542559.CEL.gz
## 21 39
## GSM542560.CEL.gz GSM542561.CEL.gz
## 67 60
## GSM542562.CEL.gz GSM542563.CEL.gz
## 74 82
## GSM542570.CEL.gz GSM542571.CEL.gz
## 26 27
## GSM542572.CEL.gz GSM542573.CEL.gz
## 26 27
## GSM542574.CEL.gz GSM542575.CEL.gz
## 28 29
## GSM542576.CEL.gz GSM542577.CEL.gz
## 28 32
1
wk (x, y) =
d2k (x, y) + s0
1 ∑
K
b(x, y) = ∑K wk (x, y)b(Zk )
k=1 wk (x, y) k=1
Fijamos una señal objetivo, Sc, que por defecto se toma Sc = 500.
Se calcula el siguiente factor de escala para el grupo de sondas i.
Sc
sfi =
M ediaAjustada{2SignalLogV aluei , 0.02, 0.98}
S =X +Y
ϕ( ab )
E(X|S = s) = a + b
Φ( ab )
sondas PM.
4.8. ROBUST MULTICHIP AVERAGE (RMA) 73
(12 + 11 + 19)/ 3
## [1] 14
(10 + 10 + 16) /3
## [1] 12
(7 + 9 + 15)/3
## [1] 10.33333
4.8.3 Resumen
Ya hemos realizado la corrección de fondo (§ 4.8.1). A los valores
obtenidos les hemos aplicado una normalización de cuantiles (§ 4.8.2).
Ahora nos queda obtener el resumen de las distintas sondas dentro
de cada conjunto (de sondas) y para cada microarray. Se aplica el
87
§ 31.2. método median polish de Tukey.87 Previamente necesitamos algo de
notación. En cada array tendremos N sondas y suponemos que tene-
mos n arrays. Por tanto la matriz de expresión a nivel de sonda será:
x = [xij ]i=1,...,N ;j=1,...,n . La sonda i-ésima en el array j-ésimo tiene
una expresión o intensidad xij . Las sondas las suponemos agrupadas
en grupos correspondientes a un mismo gen. Denotamos el grupo k-
ésimo de sondas con Sk . Por tanto, Sk ⊂ {1, . . . , N }. Por ejemplo,
el conjunto Sk = {i1 , . . . , i|Sk | }, es decir, corresponde con las filas
{i1 , . . . , i|Sk | } de la matrix x original. Por simplificar la notación to-
maremos yrj = xir ,j y por tanto
gse21779_rma = affy::rma(gse21779raw)
gse21779_mas5 = affy::mas5(gse21779raw)
76 CAPÍTULO 4. MICROARRAYS
save(gse21779_rma,file=paste(dirTamiData,"gse21779_rma.rda",sep=""))
save(gse21779_mas5,file=paste(dirTamiData,"gse21779_mas5.rda",sep=""))
load(paste(dirTamiData,"gse21779_rma.rda",sep=""))
load(paste(dirTamiData,"gse21779_mas5.rda",sep=""))
library(geneplotter)
geneplotter::multidensity(exprs(gse21779_rma))
geneplotter::multidensity(exprs(gse21779_mas5))
graphics::boxplot(exprs(gse21779_rma))
graphics::boxplot(exprs(gse21779_mas5))
bgcorrect.methods()
normalize.methods(gse21779raw)
(a) (b)
(c) (d)
Figura 4.5: a) Estimadores kernel de densidad para los chips una vez hemos aplicado el procedimiento RMA a los
datos gse21779. b) Lo mismo con el método MAS5. c) Boxplot para los niveles de expresión de los datos gse21779 con
método RMA. d) Lo mismo que el punto (c) pero con el método MAS5.
78 CAPÍTULO 4. MICROARRAYS
pmcorrect.methods()
express.summary.stat.methods()
mas5
load(paste(dirTamiData,"gse1397raw.rda",sep=""))
annotation(gse1397raw)
## [1] "GPL96"
library(limma)
exprs1 = normalizeBetweenArrays(exprs(gse1397raw),method = "quantile")
Datos de microarrays
5.1 Introducción
Comentaremos los bancos de datos que utilizamos en el resto del
curso. Son datos de expresión de genes obtenidos utilizando micro-
arrays. Algunos van incorporados en los paquetes de R/Bioconductor
como los datos golub (en [112]) o los datos ALL (en [86]). Se utilizan
como ejemplos en muchos paquetes y en artículos. Es interesante ana-
lizarlos y conocerlos. También se muestra en este tema el uso de la
clase Biobase::ExpressionSet. Esta clase permite el manejo de datos
de expresión obtenidos con microarrays. Veremos también cómo bajar
datos de repositorios públicos.
5.2 sample.ExpressionSet
Los datos Biobase::sample.ExpressionSet. El experimento tiene 26
muestras y 500 genes. Sobre las muestras conocemos tres variables (o
covariables): sex, type (caso y control) y score. La última covariable
no es categórica, es una covariable continua. Estos datos de expresión
están almacenados en un objeto de clase ExpressionSet. Para poder
utilizar esta estructura de datos hemos de cargar el paquete [57, Bio-
base].
library(Biobase)
data(sample.ExpressionSet)
help(sample.ExpressionSet)
varLabels(sample.ExpressionSet)
81
82 CAPÍTULO 5. DATOS DE MICROARRAYS
sample.ExpressionSet$type
phenoData(sample.ExpressionSet)
exprs(sample.ExpressionSet)
annotation(sample.ExpressionSet)
## [1] "hgu95av2"
table(sample.ExpressionSet$sex)
##
## Female Male
## 11 15
5.3. DATOS GOLUB 83
table(sample.ExpressionSet$type)
##
## Case Control
## 15 11
summary(sample.ExpressionSet$score)
data(golub,package= "multtest")
golub[1,]
golub.gnames[1,]
## [1] "36"
## [2] "AFFX-HUMISGF3A/M97935_MA_at (endogenous control)"
## [3] "AFFX-HUMISGF3A/M97935_MA_at"
golub.cl
## [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
## [24] 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1
información original que estamos haciendo y que, por lo tanto, afecta de un modo
fundamental las conclusiones que obtengamos en cualquier tratamiento estadístico
posterior. Y lo peor: no sabemos de un modo claro cómo afectan estos resultados.
5.4. DATOS ALL 85
golub.cl
## [1] ALL ALL ALL ALL ALL ALL ALL ALL ALL ALL ALL
## [12] ALL ALL ALL ALL ALL ALL ALL ALL ALL ALL ALL
## [23] ALL ALL ALL ALL ALL AML AML AML AML AML AML
## [34] AML AML AML AML AML
## Levels: ALL AML
90 90
El script de R con todo
En el paquete [62] tenemos los datos originales. Tanto las mues- el preprocesado descri-
tras que se utilizaron para entrenar el procedimiento como las que se to podemos encontrarlo
utilizaron para evaluarlo. en http://svitsrv25.
epfl.ch/R-doc/library/
multtest/doc/golub.R y
5.4 Datos ALL en la documentación del
paquete [112].
Para una versión ampliada de esta sección podemos consultar [68,
capítulo 1]. Los datos ALL son microarrays de 128 individuos distin-
tos con leucemia linfoblástica aguda (ALL). De estos individuos 95
corresponden a leucemia linfoblástica precursora aguda de células B
y y 33 son leucemia linfoblástica precursora aguda de células T. Son
enfermedades bastante distintas y por ello se consideran por separado.
Habitualmente trabajaremos con las muestras de leucemia linfoblás-
tica precursora aguda de células B. Los datos han sido preprocesados
utilizando el método RMA (robust multichip average) implementado
en el paquete [74, affy] con la función affy::rma y están almacena-
dos en forma de un Biobase::ExpressionSet. Empezamos cargando los
datos.
library(Biobase)
library(ALL)
data(ALL)
bcell = grep("^B",as.character(ALL$BT))
types = c("NEG","BCR/ABL")
moltyp = which(as.character(ALL$mol.biol) %in% types)
bcrneg = ALL[,intersect(bcell,moltyp)]
ExpressionSet
Es una estructura de datos que nos permite mantener en un solo
objeto toda la información que relativa a un experimento con micro-
arrays.
Para poder utilizar esta clase necesitamos el paquete [57, Biobase].
Lo cargamos (la clase y los métodos que luego vamos a utilizar).
pacman::p_load(Biobase)
¿Qué necesitamos?
Supongamos que tenemos la información por separado y queremos
construir un ExpressionSet. ¿Qué datos nos describen un experimento
genómico de alto rendimiento? Podemos distinguir la siguiente infor-
mación:
pacman::p_load("tamidata")
finput = system.file("extdata","n06_expr.txt",package="tamidata")
exprs0 = read.table(file = finput,header = TRUE,sep="\t")
class(exprs0)
## [1] "data.frame"
exprs0 = as.matrix(exprs0[,-1])
class(exprs0)
## [1] "matrix"
dim(exprs0)
## [1] 22215 54
colnames(exprs0)
Y podemos ver
head(exprs0,n=1)
finput = system.file("extdata","n06_gene_attributes.txt",package="tamidata")
rn = read.table(file = finput,header = TRUE,sep="\t")
rownames(exprs0) = rn[,1]
Datos fenotípicos
Es la información que tenemos de las distintas muestras. Será una
matriz de datos (un data.frame) con tantas filas como muestras, n, y
con tantas columnas como variables tenemos. Estas variables que nos
describen las muestras podemos llamarlas covariables (una denomina-
ción muy estadística).
5.5. CONSTRUYENDO UN EXPRESSIONSET 89
finput = system.file("extdata","n06_sample_attributes.txt",
package="tamidata")
pd0 = read.table(finput,sep = "\t",header=TRUE)
dim(pd0)
## [1] 54 14
Es necesario que los nombres de las filas de pd0 coincidan con los
nombres de las columnas de exprs0 ya que nos están dando covariables
relativas a estas muestras.
rownames(pd0) = colnames(exprs0)
summary(pd0)
## mutant : 1
Median :27.00
## WT : 9
Mean :27.23
## NA's :25
3rd Qu.:40.00
## Max. :54.00
## NA's :1
## adherence per3
## adherent :12 Min. :4.000
## not adherent: 5 1st Qu.:4.000
## partial : 6 Median :5.000
## NA's :31 Mean :5.452
## 3rd Qu.:5.000
## Max. :9.000
## NA's :23
sapply(pd0,class)
sampleNames(datosfenotipo)
head(pData(datosfenotipo))
save(neve06,file="neve06.rda")
data(gse6647,package="tamidata")
dim(gse6647)
## Features Samples
## 6103 8
head(pData(gse6647))
## type
## GSM153907.CEL.gz wt
## GSM153908.CEL.gz edc3D
## GSM153909.CEL.gz wt
## GSM153910.CEL.gz edc3D
## GSM153911.CEL.gz wt
## GSM153912.CEL.gz edc3D
geneplotter::multidensity(exprs(gse6647))
boxplot.matrix(exprs(gse6647))
(a) (b)
(a) (b)
Figura 5.2: Datos gse6647: estimadores de densidad y diagramas de cajas utilizando [151, ggplot2].
library(ALL)
ALL
exprs(ALL)
pData(ALL)
annotation(ALL)
## [1] "hgu95av2"
names(pData(ALL))
ALL$BT
## [1] B2 B2 B4 B1 B2 B1 B1 B1 B2 B2 B3 B3 B3 B2 B3
## [16] B B2 B3 B2 B3 B2 B2 B2 B1 B1 B2 B1 B2 B1 B2
## [31] B B B2 B2 B2 B1 B2 B2 B2 B2 B2 B4 B4 B2 B2
## [46] B2 B4 B2 B1 B2 B2 B3 B4 B3 B3 B3 B4 B3 B3 B1
## [61] B1 B1 B1 B3 B3 B3 B3 B3 B3 B3 B3 B1 B3 B1 B4
## [76] B2 B2 B1 B3 B4 B4 B2 B2 B3 B4 B4 B4 B1 B2 B2
## [91] B2 B1 B2 B B T T3 T2 T2 T3 T2 T T4 T2 T3
## [106] T3 T T2 T3 T2 T2 T2 T1 T4 T T2 T3 T2 T2 T2
## [121] T2 T3 T3 T3 T2 T3 T2 T
## Levels: B B1 B2 B3 B4 T T1 T2 T3 T4
ALL[,selcol]
5.9 GSE21779
Hemos elegido los datos que en dicha base de datos tienen el identi-
ficador GSE21779. Podemos buscarlos utilizando la página web http:
//www.ncbi.nlm.nih.gov/geo/ o bien podemos acceder directamen-
te a esta dirección http://www.ncbi.nlm.nih.gov/sites/GDSbrowser?
acc=GDS4128. Bajamos los ficheros CEL (están en formato comprimi-
do gzip).
Sabiendo el identificador de los datos y que tienen los datos de
expresión originales los podemos bajar del siguiente modo. Primero
cargamos el paquete [38, GEOquery].
5.10. GSE1397 97
library(GEOquery)
gcel = getGEOSuppFiles("GSE21779")
library(affy)
gse21779 = ReadAffy()
save(gse21779,file = "gse21779.rda")
save(gse21779,file=paste(dirTamiData,"gse21779.rda",sep=""))
library(ArrayExpress)
geod21779 = ArrayExpress("E-GEOD-21779")
geod21779.rma = rma(geod21779)
save(geod21779.rma,file=paste(dirTamiData,"geod21779.rma.rda",sep=""))
5.10 GSE1397
96 96
El síndrome de Down es una enfermedad causada por la apari- El uso de estos datos y
ción de un copia extra total o parcial del cromosoma 21. Analizaremos parte del análisis aparecen en
si los genes de este cromosoma muestra una sobre expresión. Además un documento que se puede
se verá que solamente es específica de estos genes y no de otros que encontrar en esta dirección.
aparecen en otros cromosomas. Los datos se pueden obtener de GEO y También he utilizado parte
del análisis que propone Ro-
drigo Santamaría.
98 CAPÍTULO 5. DATOS DE MICROARRAYS
pacman::p_load("Biobase","GEOquery")
gse1397raw = getGEO("GSE1397")[[1]]
annotation(gse1397raw) = "hgu133a"
Los datos fenotípicos de las muestras los podemos ver con (no
mostramos)
pData(gse1397raw)
varLabels(gse1397raw)
head(pData(gse1397raw)[,"title"])
exprs(gse1397raw)
(ts21=c(grep("T.*21.*cerebrum", as.character(pData(gse1397raw)[,"title"])),
grep("TS21.*cerebellum", as.character(pData(gse1397raw)[,"title"]))))
(eu=c(grep("Euploid.*cerebrum)", as.character(pData(gse1397raw)[,"title"])),
grep("Euploid.*[Cc]erebellum", as.character(pData(gse1397raw)[,"title"]))))
pData(gse1397raw)[eu,"title"]
5.10. GSE1397 99
pData(gse1397raw)[ts21,"title"]
gse1397raw = gse1397raw[,c(eu,ts21)]
tissue = factor(rep(c(1,2,1,2),c(4,3,4,3)),levels=1:2,
labels=c("Cerebrum","Cerebellum"))
type = factor(c(rep(1,7),rep(2,7)),levels=1:2,labels=c("Euploid","TS21"))
GROUP = as.numeric(type) - 1
pData(gse1397raw) = data.frame(tissue,type)
save(gse1397raw,file="gse1397raw.rda")
97
Vamos a mostrar los estimadores kernel de la densidad en su 97 El análisis que acaba-
escala original. Primero cargamos el paquete [17, affyPLM] que, entre mos de ver desde bajar
otras cosas, nos permite obtener estos estimadores con facilidad. los datos hasta obtener el
ExpressionSet lo podemos
library(affyPLM) encontrar en http://www.
uv.es/ayala/docencia/
No tenemos los ficheros .CEL que necesitamos para preprocesar los tami/Rmd/gse1397.html.
datos. Por ello recurrimos a la función normalizeBetweenArrays()
del paquete [130, limma].
library(limma)
gse1397 = gse1397raw
exprs(gse1397) = normalizeBetweenArrays(exprs(gse1397raw))
df = data.frame(gene = featureNames(gse1397),exprs(gse1397))
df1 = melt(df,id=c("gene"))
png(paste(dirTamiFigures,"gse1397normden.png",sep=""))
ggplot(df1,aes(x=value,colour=variable,group=variable)) +
geom_density(kernel = "epanechnikov",fill=NA) + xlim(0,1000)
dev.off()
98 98
gse1397.
Los autores introdujeron información adicional sobre las filas (ge-
nes) que podemos ver (no lo mostramos) con
fData(gse1397raw)
names(fData(gse1397raw))
100 CAPÍTULO 5. DATOS DE MICROARRAYS
## [1] "ID"
## [2] "GB_ACC"
## [3] "SPOT_ID"
## [4] "Species Scientific Name"
## [5] "Annotation Date"
## [6] "Sequence Type"
## [7] "Sequence Source"
## [8] "Target Description"
## [9] "Representative Public ID"
## [10] "Gene Title"
## [11] "Gene Symbol"
## [12] "ENTREZ_GENE_ID"
## [13] "RefSeq Transcript ID"
## [14] "Gene Ontology Biological Process"
## [15] "Gene Ontology Cellular Component"
## [16] "Gene Ontology Molecular Function"
pacman::p_load("Biobase","GEOquery")
gcel = getGEOSuppFiles("GSE20986")
setwd("GSE20986/")
Además nos ha bajado un fichero tar del cual hemos de extraer los
distintos ficheros CEL. En Linux lo haremos con5
contrar en http://bioinformatics.knowledgeblog.org/2011/06/20/
analysing-microarray-data-in-bioconductor/. En lo que sigue utilizare-
mos parte del análisis que se propone allí. La referencia original del estudio es
[23].
5 En Windows podemos usar el Winrar.
5.12. GSE34764 101
gse20986raw = affy::ReadAffy()
save(gse20986raw,file="gse20986raw.rda")
pacman::p_load("gcrma","hgu133plus2probe")
gse20986 = gcrma::gcrma(gse20986raw)
save(gse20986,file="gse20986.rda")
5.12 GSE34764
Consideremos los datos de GEO con identificador GSE34764. Ne-
cesitamos el paquete [38, GEOquery]. Lo cargamos.
6 Los datos que hemos bajado con la función getGEO ya estaban preprocesa-
dos utilizando las mismas funciones que usamos aquí. Lo he hecho para mostrar
cómo se hace o bien porque podemos querer utilizar algún otro procedimiento de
preprocesado.
102 CAPÍTULO 5. DATOS DE MICROARRAYS
library(GEOquery)
getGEOSuppFiles("GSE34764")
setwd("GSE30129/")
library(oligo)
celFiles = list.celfiles()
gse34774 = read.celfiles(celFiles)
save(gse34774,file="gse34774.rda")
5.13 ArrayExpress
En § 5.5 hemos visto cómo construir un ExpressionSet cuando te-
nemos los datos de expresión, los fenotípicos y los de anotación. Si
consultamos la referencia original [105] vemos que los autores han
subido toda la información del experimento a ArrayExpress. Real-
mente gran parte del trabajo que hicimos en esa sección la podíamos
ahorrar bajando los datos ya preparados de esta base de datos. Lo po-
demos hacemos hacer con el paquete [80, ArrayExpress] del siguiente
modo.
library(ArrayExpress)
rawset = ArrayExpress("E-TABM-157")
5.14 Varios
Esta sección es una especie de cajón de sastre que contiene cosas
que no he sabido colocar elegantemente en el resto del tema.
data(gse1397,package="tamidata")
write.exprs(gse1397,file="gse1397.txt")
Y luego podemos abrir este fichero con Calc102 o con nuestra apli- 102 La versión libre de Excel
cación preferida. que tenemos en LibreOffice.
5.15 Ejercicios
Ej. 14 — Se pide construir un ExpressionSet. Este ExpressionSet
ha de tener la siguiente matriz de expresión.
## [,1] [,2] [,3] [,4] [,5]
## [1,] 23.21 25.24 22.87 21.36 23.49
## [2,] 23.09 21.38 21.49 22.76 22.96
## [3,] 23.51 23.03 25.02 24.04 20.04
## [4,] 23.03 24.50 24.09 22.88 26.09
## [5,] 21.00 22.14 23.28 23.75 22.75
## [6,] 23.88 22.10 24.46 24.15 23.78
## [7,] 23.46 21.87 21.39 25.01 23.33
## [8,] 22.68 21.74 23.79 23.07 24.23
## [9,] 23.14 22.48 22.37 22.94 23.98
## [10,] 23.16 23.40 23.82 20.90 22.75
## [11,] 23.27 20.58 22.93 23.12 23.45
## [12,] 24.97 23.25 23.76 22.31 21.87
## [13,] 22.74 24.48 24.60 21.83 24.03
## [14,] 23.20 25.45 23.01 22.78 22.45
## [15,] 24.40 24.56 24.22 24.22 25.90
## [16,] 24.27 23.91 21.57 20.61 21.02
## [17,] 24.37 20.93 22.13 22.49 22.44
## [18,] 22.31 22.28 24.82 23.14 23.99
## [19,] 25.40 22.58 23.45 21.93 23.61
## [20,] 23.08 23.84 20.54 23.40 22.29
Los nombres de las filas ha de ser
## [1] "g1" "g2" "g3" "g4" "g5" "g6" "g7"
## [8] "g8" "g9" "g10" "g11" "g12" "g13" "g14"
## [15] "g15" "g16" "g17" "g18" "g19" "g20"
Los nombres de las muestras serán
## [1] "m1" "m2" "m3" "m4" "m5" "m6" "m7"
## [8] "m8" "m9" "m10" "m11" "m12" "m13" "m14"
## [15] "m15" "m16" "m17" "m18" "m19" "m20"
Como datos fenotípicos (covariables que describen las columnas) han
de ser las siguientes
## tipo crecimiento
## 1 1 0.30
## 2 2 0.23
## 3 2 0.34
## 4 1 0.24
## 5 2 0.45
Datos de RNA-seq
6.1 Introducción
En este tema trabajamos con datos obtenidos mediante la técnica
conocida como RNA-Seq. En http://rnaseq.uoregon.edu/ tenemos
una introducción muy simple y clara. [108] da una buena visión ge-
neral. En [39, RnaSeqTutorial] tenemos una presentación general de
cómo trabajar con estos datos en el contexto de R/Bioconductor. Un
texto general que trata lo relativo al análisis de este tipo de datos
es [82]. Una referencia más breve pero muy interesante es [36] donde
también da una visión global del análisis de este tipo de información.
En este manual se asume que se trabaja con un genoma de refe-
rencia. Los procedimientos que vamos a estudiar asumen este punto
de partida.
De un modo análogo a § 4 y § 5 comentaremos este tipo de infor-
mación de expresión génica.103 103
En el momento actual
uno de los que más interés
despierta.
6.2 Flujo de trabajo con RNA-seq
Un estudio de este tipo implica la realización de los siguientes
pasos ([108]):
1. Diseño experimental.
105
106 CAPÍTULO 6. DATOS DE RNA-SEQ
6.3 Repositorios
Los repositorios donde podemos encontrar este tipo de datos son
NCBI en los Estados Unidos, EMBL en Europa y DDBJ en Japón.105 105 Son los básicos como pa-
En NCBI GEO también hay datos de secuencias y podemos acceder ra datos de microarrays tene-
a ellos utilizando [38, GEOquery]. En concreto las direcciones son mos NCBI GEO y EBI Arra-
yExpress.
NCBI SRA http://www.ncbi.nlm.nih.gov/sra Posiblemente es
la mayor de las bases de datos. No almacena lecturas alinea-
das. En NCBI GEO sí que tenemos algunos bancos de datos
con lecturas alineadas sobre un genoma de referencia.
EBI ENA http://www.ebi.ac.uk/ena
DDBJ http://www.ddbj.nig.ac.jp
En lo que sigue utilizamos fundamentalmente la primera base de da-
tos y, a veces, la segunda. Cada una de estas bases de datos puede
ser consultada en línea y bajar los datos desde la propia página. Tam-
bién usaremos en lo que sigue herramientas para hacerlo desde R, por
ejemplo, [165, SRAdb].
En las secciones § 6.4 y § 6.5. comentamos distintos formatos para
almacenar lecturas cortas. También comentamos paquetes R/Biocon-
ductor para trabajar con estos formatos.
library(ShortRead)
109
En ?? vemos cómo pode- Vamos a ver sus funcionalidades utilizando el SRR1293399_1.fastq.109
mos bajar estos datos. En esta sección suponemos fijado el directorio de trabajo a donde te-
nemos los datos.
110
Veremos que tarda lo su- Leemos con ShortRead::readFastq.110
yo en leer los datos.
fq0 = readFastq("SRR1293399_1.fastq")
fqsample = FastqSampler("SRR1293399_1.fastq",10000)
fq0 = yield(fqsample)
class(fq0)
## [1] "ShortReadQ"
## attr(,"package")
## [1] "ShortRead"
fq0
## class: ShortReadQ
## length: 10000 reads; width: 50 cycles
6.5. FORMATO FASTQ 109
111
Subsetting Obviamente tiene solamente 10000 lecturas. Podemos seleccionar111
del modo habitual. Por ejemplo, la primera sería
fq0[1]
## class: ShortReadQ
## length: 1 reads; width: 50 cycles
fq0[3:10]
## class: ShortReadQ
## length: 8 reads; width: 50 cycles
sread(fq0[1000])
sread(fq0)
width(fq0)
quality(fq0[1000])
## class: SFastqQuality
## quality:
## A BStringSet instance of length 1
## width seq
## [1] 50 ffffffffffffffffeff...fffeffefffff`ddbdd
110 CAPÍTULO 6. DATOS DE RNA-SEQ
encoding(quality(fq0))
## ; < = > ? @ A B C D E F G H I J
## -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10
## K L M N O P Q R S T U V W X Y Z
## 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
## [ \\ ] ^ _ ` a b c d e f g h i
## 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
fls = dir(paste(dirTamiData,"SRP042140/fastq",sep=""),"*fastq$",full=TRUE)
113
A los usuarios de Win- Generamos un informe y lo visualizamos.113
dows es probable que el codi-
go que sigue no les funcione. browseURL(report(SRP042140_1.qa))
¿Les extraña?
Es un informe muy interesante. Notemos que estos datos ya es-
114
Son datos obtenidos de tán previamente filtrados114 y por ello algunas de las características
un repositorio público. evaluadas no tienen sentido.
Podemos ver la información contenida en SRP042140.qa con
show(SRP042140_1.qa)
## class: FastqQA(10)
## QA elements (access with qa[["elt"]]):
## readCounts: data.frame(1 3)
## baseCalls: data.frame(1 5)
## readQualityScore: data.frame(512 4)
## baseQuality: data.frame(94 3)
## alignQuality: data.frame(1 3)
## frequentSequences: data.frame(50 4)
## sequenceDistribution: data.frame(357 4)
## perCycle: list(2)
## baseCall: data.frame(249 4)
## quality: data.frame(1800 5)
## perTile: list(2)
## readCounts: data.frame(0 4)
## medianReadQualityScore: data.frame(0 4)
## adapterContamination: data.frame(1 1)
SRP042140_1.qa[["readCounts"]]
SRP042140_1.qa[["baseCalls"]]
## A C G
## SRR1293399_1.fastq 10600637 12762822 12873094
## T N
## SRR1293399_1.fastq 13753938 9509
head(SRP042140_1.qa[["frequentSequences"]])
## sequence
## 1 GTGTCAGTCACTTCCAGCGGTCGTATGCCGTCTTCTGCTTGAAAAAAAAA
## 2 TAGCTTATCAGACTGATGTTGACGTGTCAGTCACTTCCAGCGGTCGTATG
## 3 TGTAAACATCCCCGACTGGAAGCGTGTCAGTCACTTCCAGCGGTCGTATG
## 4 AACTGGCCCTCAAAGTCCCGCTGTGTCAGTCACTTCCAGCGGTCGTATGC
## 5 TGTCAGTCACTTCCAGCGGTCGTATGCCGTCTTCTGCTTGAAAAAAAAAA
## 6 TGTAAACATCCCCGACTGGAAGCTGTGTCAGTCACTTCCAGCGGTCGTAT
## count type lane
## 1 94635 read SRR1293399_1.fastq
## 2 55085 read SRR1293399_1.fastq
## 3 37265 read SRR1293399_1.fastq
## 4 28687 read SRR1293399_1.fastq
## 5 18234 read SRR1293399_1.fastq
## 6 13152 read SRR1293399_1.fastq
head(SRP042140_1.qa[["perCycle"]]$baseCall,n=10)
head(SRP042140_1.qa[["perCycle"]]$quality,n=10)
## 44 1 K 11 80 SRR1293399_1.fastq
## 45 1 L 12 3411 SRR1293399_1.fastq
## 46 1 M 13 625 SRR1293399_1.fastq
## 51 1 R 18 137 SRR1293399_1.fastq
## 53 1 T 20 6936 SRR1293399_1.fastq
## 54 1 U 21 907 SRR1293399_1.fastq
## 55 1 V 22 1140 SRR1293399_1.fastq
## 56 1 W 23 88 SRR1293399_1.fastq
## 57 1 X 24 757 SRR1293399_1.fastq
SRR1293399_1.bam
SRR1293400_1.bam
SRR1293401_1.bam
library(Rsamtools)
dirActualData = paste(dirTamiData,"SRP042140_sra/",sep="")
sampleTable = read.table(paste(dirActualData,"bamfiles.txt",sep=""))
fls = paste(dirActualData,"aligned/",sampleTable[,1],sep="")
bamLst = BamFileList(fls, index=character(),yieldSize=100000,obeyQname=TRUE)
library(GenomicFeatures)
gtffile = paste(dirTamiData,
"ENSEMBL.homo_sapiens.release-75/Homo_sapiens.GRCh37.75.gtf",sep="")
6.9 Bowtie2
117 117
http://bowtie-bio.
sourceforge.net/ Es una herramienta software para alinear lecturas cortas sobre
bowtie2/manual.shtml secuencias de referencia largas. Soporta distintos modos de alinea-
118
gapped miento: con huecos118 , locales y con lecturas apareadas119 . La salida
119 del programa la realiza en formato SAM.
Paired-end
El programa bowtie2 utiliza un fichero de índices de clase Bowtie
2 y ficheros con lecturas secuenciadas y produce un fichero en formato
SAM.
¿Qué es alinear? Tomamos una lectura o secuencia corta y preten-
demos encontrar en una secuencia larga donde es más similar, en que
punto hay una mayor similitud respecto de la secuencia larga o de
referencia. ¿Cuál es el resultado que obtenemos después de alinear?
La secuencia corta es colocada sobre una parte de la secuencia de
referencia indicando en qué puntos se produce una correspondencia
6.9. BOWTIE2 115
120
Gaps. e indicando los huecos120 que se han tenido que introducir en una u
otra de las secuencias para conseguir la mejor correspondencia posible
entre dichas secuencias.
Read: GACTGGGCGATCTCGACTTCG
||||| |||||||||| |||
Reference: GACTG--CGATCTCGACATCG
Mediante la línea vertical mostramos en qué puntos hay una corres-
pondencia correcta mientras que con un guión en una u otra secuencia
indicamos en qué posiciones hemos debido de incorporar un hueco pa-
ra poder hacer corresponder ambas secuencias.
Notemos que no estamos seguros de que efectivamente la secuencia
corta se haya originado en este punto. Es una hipótesis. La mejor que
se puede conjeturar pero no es seguro ni mucho menos. En muchas
ocasiones no se puede encontrar una correspondencia.
Dos tipos de alineamientos son considerados: alineamiento de
extremo a extremo o alineamiento global121 y alineamiento lo- 121
End-to-end alignment.
cal.122 En la primera opción toda la secuencia corta es alineada. En 122
Local alignment.
el segundo tipo permitimos que uno o los dos extremos contengan ba-
ses no alineadas. En Bowtie2 la opción local se indica --local para el
alineamiento local mientras que la opción global se asume por defecto.
Hemos de evaluar la calidad del alineamiento. Para ello definimos
una puntuación asociada a cada posible correspondencia. Lo que po-
demos llamar una función objetivo. La idea es que cuanto mayor sea
la función objetivo mejor es el alineamiento. Realmente penalizamos
cada error en la correspondencia. Tendremos una penalización por co-
rrespondencia errónea, una penalización por cada hueco. En el caso
de alineamiento local sumaremos un valor por cada correspondencia.
Finalmente el valor de la función objetivo nos cuantifica la calidad
final de la correspondencia conseguida. En concreto se consideran los
siguientes valores que se suman (bajando o subiendo) para calcular el
valor de la función objetivo.
–ma Sumamos un valor positivo por cada correspondencia (para ali-
neamiento local).
–mp Penalización (restamos) por una correspondencia errónea.
–np Penalización por tener un valor N (esto es una base no especifi-
cada) en la secuencia corta o en la larga de referencia.
–rdg Penalización por hueco en secuencia corta.
–rfg Penalización por hueco en secuencia de referencia.
Obviamente mediante algún procedimiento encontraremos siempre
una correspondencia. No necesariamente esta correspondencia la he-
mos de considerar suficientemente buena. ¿Cuándo la consideraremos
aceptable? Lo que se hace es fija un umbral por debajo del cual el ali-
neamiento no se acepta. Este umbral lógicamente ha de depender de
la longitud de la lectura corta. El valor de este umbral que por defecto
(aunque es configurable) tiene definido Bowtie2 es, para alineamiento
global,
−0.6 − 0.6 · L, (6.2)
siendo L la longitud de la lectura. Para alineamiento local el valor es
20 + 8 · ln(L). (6.3)
116 CAPÍTULO 6. DATOS DE RNA-SEQ
bowtie2 -x ~/DOCENCIA/tami-data/Homo_sapiens/Ensembl
,→ /GRCh37/Sequence/Bowtie2Index/genome -U fastq
,→ /SRR1293399_1.fastq -S aligned/SRR1293399_1.
,→ sam
4. Alineamos con
tophat2 -o file_tophat_out genome SRR479053_1.fastq
,→ SRR479053_2.fastq
samtools sort -n file_tophat_out/accepted_hits.
,→ bam_sorted
Alineamos.
tophat2 -o file_tophat_out genome SRR479053_1.fastq
,→ SRR479053_2.fastq
samtools sort -n file_tophat_out/accepted_hits.bam_sorted
data(parathyroidGenesSE,package="parathyroidSE")
se = parathyroidGenesSE
class(se)
## [1] "RangedSummarizedExperiment"
## attr(,"package")
## [1] "SummarizedExperiment"
Es un SummarizedExperiment::RangedSummarizedExperiment y
será nuestra clase de referencia cuando trabajamos con datos de RNA-
125
Es muy conveniente leer seq.125 ¿Cuántos genes y muestras tenemos?
la viñeta de [102, Summari-
zedExperiment]. dim(se)
## [1] 63193 27
126
Es la análoga a Bio- La matriz con los conteos nos la da GenomicRanges::assay.126
base::exprs para Bioba-
se::ExpressionSet. assay(se)
Veamos las tres primeras filas (genes) y las tres primeras columnas
(muestras).
assay(se)[1:3,1:3]
colData(se)
Es un IRanges::DataFrame.
class(colData(se))
## [1] "DataFrame"
## attr(,"package")
## [1] "IRanges"
names(colData(se))
colData(se)[,"treatment"]
colData(se)$treatment
rowRanges(se)
rownames(se)
head(rownames(se))
128 128
En esta sección he-
mos visto cómo manejar
un la clase GenomicRan-
6.12 GSE64099 ges::SummarizedExperiment
y sus métodos asociados.
Bajamos los datos de GEO.
wget ftp.ncbi.nlm.nih.gov/geo/series/GSE64nnn/GSE64099/
,→ suppl/GSE64099_RAW.tar
tar xvf GSE64099_RAW.tar
gzip -d *
rm GSE64099_RAW.tar
Construimos un ExpressionSet.
120 CAPÍTULO 6. DATOS DE RNA-SEQ
library(Biobase)
exprs0 = CountAll
rownames(exprs0) = EntrezAll
colnames(exprs0) = c("GSM1564328","GSM1564331","GSM1564329","GSM1564332",
"GSM1564327","GSM1564330","GSM1564333")
type = c(2,1,2,1,1,2,2)
type = factor(type,levels=1:2,labels=c("Wild-type","Smchd1"))
type = data.frame(type)
rownames(type) = colnames(exprs0)
datosfenotipo = new("AnnotatedDataFrame", data = type)
sampleNames(datosfenotipo)
datosexperimento = new('MIAME',name='GSE64099',
lab='Molecular Medicine Division, The Walter and Eliza Hall Institute
of Medical Research',
contact ='mritchie@wehi.edu.au',
title = ' Transcriptome profiling for genes transcriptionally
regulated by Smchd1 in lymphoma cell lines',
url = 'http://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE64099')
gse64099 = new("ExpressionSet",exprs=exprs0,phenoData = datosfenotipo,
experimentData = datosexperimento,annotation = "MusMusculus")
nullsum = apply(exprs(gse64099),1,sum)==0
gse64099 = gse64099[!nullsum,]
x = read.table(file="GSE63776_PANC1_counts.txt",header=TRUE)
exprs0 = as.matrix(x[,-1])
rownames(exprs0) = x[,"Gene"]
type = factor(rep(1:2,each=3),levels=1:2,labels=c("siControl","siTCF7L2"))
pd0 = data.frame(type)
rownames(pd0) = colnames(exprs0)
datosfenotipo = new("AnnotatedDataFrame", data = pd0)
datosexperimento = new('MIAME',name='GSE63776',
lab='Seth Frietze and Farnham P',
contact ='seth.frietze@unco.edu',
title = ' ',abstract = 'We have compared the genome-wide effects on the
transcriptome after treatment with ICG-001 (the specific CBP inhibitor)
versus C646, a compound that competes with acetyl-coA for the Lys-coA
binding pocket of both CBP and p300. We found that both drugs cause
large-scale changes in the transcriptome of HCT116 colon cancer cells and
PANC1 pancreatic cancer cells, and reverse some tumor-specific changes in
gene expression. Interestingly, although the epigenetic inhibitors affect
cell cycle pathways in both the colon and pancreatic cancer cell lines,
the WNT signaling pathway was affected only in the colon cancer cells.
Notably, WNT target genes were similarly down-regulated after treatment
of HCT116 with C646 as with ICG-001.',
url = 'http://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE63776',
other = list(notes = 'Public on Jan 07, 2015'))
gse63776 = new("ExpressionSet",exprs=exprs0,phenoData = datosfenotipo,
experimentData = datosexperimento,annotation =
"Illumina HiSeq 2000 (Homo sapiens)")
save(gse63776,file="gse63776.rda")
6.14.1 RPKM
138
El primer método de normalización se propuso en [103]. Su- 138 Reads per kilobase per
pongamos que denotamos el conteo de interés por C. Es el número de million.
lecturas alineadas sobre la característica de interés (exon, gen, etc.).
El total de lecturas que podemos alinear es N (o tamaño de la libre-
ría). Y denotamos por L la longitud de la característica de interés en
bp. Se define el RPKM como el siguiente cociente
109 C
RP KM = . (6.4)
NL
Esta cuantificación de la expresión del gen nos permite comparar genes
entre sí dentro de una misma muestra o librería.
En el paquete [162, geneLenDataBase] tenemos las longitudes de
los distintos transcritos para distintos organismos. En el siguiente có-
digo leemos los datos correspondientes a humanos (versión 19).
pacman::p_load("geneLenDataBase")
data(hg19.ensGene.LENGTH)
head(hg19.ensGene.LENGTH)
con
(r) mj − xij mr − xir
wij = + .
mj xij mr xir
6.14. NORMALIZACIÓN DE RNA-SEQ 125
pacman::p_load(SummarizedExperiment)
counts0 = assay(PRJNA297664)
pacman::p_load(edgeR)
deg.n = DGEList(counts = counts0, group = rep(1,ncol(counts0)))
deg.n = calcNormFactors(deg.n, method = "TMM")
deg.n = estimateCommonDisp(deg.n)
counts1 = deg.n$pseudo.counts
pacman::p_load("ggplot2")
counts0 = data.frame(counts0)
df0 = reshape2::melt(counts0)
png(paste0(dirTamiFigures,"PRJNA297664_counts0_ecdf.png"))
ggplot(df0, aes(x=value, colour = variable)) + stat_ecdf()
dev.off()
png(paste0(dirTamiFigures,"PRJNA297664_counts0_ecdf.png"))
ggplot(df0, aes(x=value, colour = variable)) + geom_density()
dev.off()
counts1 = data.frame(counts1)
df0 = reshape2::melt(counts1)
png(paste0(dirTamiFigures,"PRJNA297664_counts0_ecdf.png"))
ggplot(df0, aes(x=value, colour = variable)) + stat_ecdf()
dev.off()
png(paste0(dirTamiFigures,"PRJNA297664_counts0_ecdf.png"))
ggplot(df0, aes(x=value, colour = variable)) + geom_density()
dev.off()
(a) (b)
(a) (b)
distintos conteos para un mismo gen. Una vez que tenemos los datos
normalizados intra gen buscamos una constante de normalización por
muestra como la correspondiente mediana en la muestra. Estas cons-
tantes son utilizadas no para normalizar directamente el conteo sino
para incorporarlo como factor que multiplica a la media del conteo en
los métodos DESeq y DESeq2.
Utilizando los mismos datos tamidata::PRJNA297664 el método
anterior lo podemos aplicar con el siguiente código.
library(Rsamtools)
library(GenomicFeatures)
sampleTable = read.table("bamfiles.txt")
dirActualData = "/home/gag/DOCENCIA/tami-data/SRP064411/sra/"
fls = paste(dirActualData,sampleTable[,1],sep="")
bamLst = BamFileList(fls, index=character(),yieldSize=100000,obeyQname=TRUE)
gtfFile = "~/DOCENCIA/tami-data/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation
txdb = makeTxDbFromGFF(gtffile, format="gtf")
genes = exonsBy(txdb, by="gene")
library(GenomicAlignments)
SRP064411_SE = summarizeOverlaps(features = genes, read=bamLst,
mode="Union",
singleEnd=TRUE, ## No son lecturas apareadas
ignore.strand=TRUE,
fragments=FALSE)
10. Tenemos que añadir los metadatos o datos fenotípicos. Son los
siguientes donde lo que aparece en la primera columna es el nom-
bre que tiene la muestra en nuestro SummarizedExperiment, los
colnames.
6.16. DATOS SIMULADOS 129
SampleName = c("GSM1900735","GSM1900737","GSM1900739","GSM1900736",
"GSM1900738","GSM1900740")
Run = c("SRR2549634","SRR2549636","SRR2549638","SRR2549635",
"SRR2549637","SRR2549639")
Treatment = factor(c(0,0,1,0,1,1),levels=0:1,labels=c("wild-type","sec66del"))
Rep = c(1,3,2,2,1,3)
colData(SRP064411_SE) = DataFrame(SampleName,Run,Treatment,Rep)
save(SRP064411_SE,file="SRP064411_SE.rda")
Expresión diferencial
131
Capítulo 7
Expresión diferencial
marginal
7.1 Introducción
Para cada uno de los genes (exones, o en general características ge-
nómicas) tenemos un valor numérico (expresión) que nos indica abun-
dancia de copias de esta característica. En resumen abundancia de la
característica en la que estamos interesados. Tenemos este valor ob-
servado para distintas muestras. De cada una de las muestras tenemos
a su vez variables que las describen: tiempos, tamaños celulares, tem-
peratura, etc. A estas variables las llamaremos en lo que sigue cova-
riables. Estas covariables pueden ser categóricas, numéricas o tiempos
de supervivencia censurados. Si la covariable tiene dos categorías en-
tonces nos define dos grupos (por ejemplo, control y tratamiento). El
caso en que queremos comparar dos grupos es el más frecuente y por
ello siempre le daremos una mayor atención.
El problema que se conoce como expresión diferencial se puede
traducir a saber si hay algún tipo de asociación entre las expresiones
observadas y los valores de la covariable. Si la covariable define dos
categorías entonces la pregunta de la asociación covariable-expresión
se puede formular como: ¿Hay diferencias entre la expresión de genes
entre dos grupos considerados? Dicho de otro modo, la expresión es
distinta bajo los tratamientos que estamos considerando.
En un primer momento vamos a adoptar la aproximación gen-a-
gen. Buscamos genes que se expresan diferencialmente sin atender a
las interacciones que puedan existir entre los distintos genes, que las
hay y las consideraremos más adelante.
Intentaremos ir planteando las cuestiones (muy) lentamente ilus-
trando continuamente lo que hacemos con R/Bioconductor.
133
134 CAPÍTULO 7. EXPRESIÓN DIFERENCIAL MARGINAL
adenotar por yj .1
Como es de uso habitual en Estadística denotaremos
∑
N ∑
n
x·j = xij ; xi· = xij ,
i=1 j=1
∑
N
xij ∑
n
xij
x̄·j = ; x̄i· = .
i=1
N j=1
n
pacman::p_load("Biobase","ALL")
data(ALL)
bcell = grep("^B",as.character(ALL$BT))
types = c("NEG","BCR/ABL")
moltyp = which(as.character(ALL$mol.biol) %in% types)
bcrneg = ALL[,intersect(bcell,moltyp)]
bcrneg.iqr = apply(exprs(bcrneg),1,IQR)
bcrneg.median = apply(exprs(bcrneg),1,median)
sel.median = (bcrneg.median > quantile(bcrneg.median,0.5))
bcrneg.sd = apply(exprs(bcrneg),1,sd)
sel.sd = (bcrneg.sd > quantile(bcrneg.sd,0.5))
bcrneg.mean = apply(exprs(bcrneg),1,mean)
sel.mean = (bcrneg.mean > quantile(bcrneg.mean,0.5))
bcrneg2 = bcrneg[sel.sd & sel.mean,]
k sobre A
Otra opción natural sería fijar un nivel de actividad mínima para
un gen y quedarnos con aquellos que superen este nivel mínimo de
actividad. Consideremos el siguiente criterio: si el nivel de expresión
mínimo es c y tenemos n muestras podemos pedir que un gen deter-
minado se considere activo si en al menos k muestras del total de n
su nivel de expresión supere este nivel mínimo de actividad.
¿Cómo hacerlo con R? Empezamos fijando el nivel mínimo c. ¿Y
cómo? Podemos ver los percentiles de todas las expresiones (todos los
genes y todas las muestras).
quantile(exprs(bcrneg))
c = 5.468801
overc[433,]
count.c = apply(overc,1,sum)
head(count.c)
table(sel.c)
## sel.c
## FALSE TRUE
## 4736 7889
library(Biobase)
library(genefilter)
f1 = kOverA(5, 5.468801)
ffun = filterfun(f1)
wh1 = genefilter(exprs(bcrneg), ffun)
table(wh1)
## wh1
## FALSE TRUE
## 4736 7889
Vamos a incorporar los otros dos criterios comentados previamen-
te. Primero necesitamos una función que nos diga si la desviación
estándar supera el valor c.
Primero vemos el modelo que nos ofrece la función kOverA.
f1 = kOverA(5, 200)
f2 = sdOverc(150)
f3 = iqrOverc(72)
ffun = filterfun(f1,f2,f3)
wh123 = genefilter(exprs(bcrneg), ffun)
table(wh123)
## wh123
## FALSE
## 12625
7.4. FOLD-CHANGE 139
annotation(ALL)
## [1] "hgu95av2"
library(hgu95av2.db)
bcrneg.filt1 = nsFilter(bcrneg,var.func=IQR,var.cutoff=0.5,
require.GOBP=TRUE)
bcrneg.filt2 = nsFilter(bcrneg,var.func=sd,var.cutoff=0.5,
require.GOBP=TRUE)
sel = intersect(featureNames(bcrneg.filt1),
featureNames(bcrneg.filt2))
bcrneg1 = bcrneg[sel,]
7.4 Fold-change
144 144
Queremos comparar dos grupos. Denotamos los valores de ex- Lo que comentamos en
presión originales con xij (respectivamente yij ) para la i-ésima carac- esta sección me ha costado
terística en la j-ésima muestra del primer grupo (respectivamente del de entender una enfermedad.
segundo grupo). A los logaritmos (en base 2 o log2) de los valores ori- Lo primero el porqué de uti-
ginales los denotamos por uij = log2 (xij ) y vij = log2 (yij ). Para cada lizarlo y luego que hay una
4 En http://www.bioconductor.org/packages/release/data/annotation/ te-
indefinición en el término en
nemos un listado de paquetes de anotación.
la literatura. Vamos a inten-
5 Observemos que ahora no pasamos la matriz de expresión sino el ExpressionSet tar aclarar qué significa an-
x̄i·
≤ −2c ,
ȳi·
o bien que
ȳi·
≥ 2c .
x̄i·
En este segundo caso el gen i se sobre expresa en el grupo 2 en relación
con el primer grupo. El término que se utiliza es sobre regulación
146
Up (down) regulation. en el primer caso y de infra regulación en el segundo.146 Se utiliza
con mucha frecuencia. Es sencillo, entendible y fácil de usar. Pero
no es una buena opción. Lo fundamental, no se tiene en cuenta la
variabilidad de las medias que estamos comparando. Una opción más
correcta la vemos posteriormente en este tema y es la utilización de
un test de la t para comparar las medias de las dos poblaciones que
estamos comparando. O versiones modificadas del t-test clásico como
la propuestas en [141] o en [129] en donde esencialmente se modifica
la estimación del error estándar.
library(Biobase)
data(gse21942,package="tamidata")
y0 = pData(gse21942)[,"FactorValue..DISEASE.STATE."]
fData(gse21942)[1,]
DDR1 = exprs(gse21942)[1,]
pacman::p_load("ggplot2")
df=data.frame(id = 1:ncol(gse21942),expression = DDR1,type = golub.cl)
ggplot(df,aes(x= id,y = expression,color = type)) + geom_point()
(a) (b)
(c) (d)
Figura 7.1: a) Perfil de expresión para el gen DDR1 utilizando casos y controles. b) Diagrama de cajas para gen DDR1
en los dos grupos. c) Perfil de expresión para el gen THRA en los dos grupos. d) Diagrama de cajas para gen DDR1
en los dos grupos.
7.7. COMPARAMOS DOS CONDICIONES 143
fData(gse21942)[7,]
THRA = exprs(gse21942)[7,]
data(gse21942,package="tamidata")
Con genefilter::rowttests
Utilizamos genefilter::rowttests.
144 CAPÍTULO 7. EXPRESIÓN DIFERENCIAL MARGINAL
tt = genefilter::rowttests(gse21942,pData(gse21942)[,"FactorValue..DISEASE.STATE."])
head(tt)
## statistic dm p.value
## 1007_s_at -2.29869931 -0.15981906 0.029492008
## 1053_at 3.44084102 0.20940361 0.001901206
## 117_at -0.08505071 -0.01110444 0.932848609
## 121_at -0.53362792 -0.02274832 0.597965094
## 1255_g_at -1.01536731 -0.04339509 0.318943716
## 1294_at -1.05030996 -0.07873761 0.302886126
##
## FALSE TRUE
## 37561 17114
Con GeneSelector::RankingTstat
Vamos a obtener todos los t-tests con GeneSelector::RankingTstat.
pacman::p_load(GeneSelector)
data(gse21942,package="tamidata")
ordT = RankingTstat(exprs(gse21942),pData(gse21942)[,"FactorValue..DISEASE.STATE."],
type="unpaired")
7.8. COMPARANDO MÁS DE DOS CONDICIONES 145
class(ordT)
## [1] "GeneRanking"
## attr(,"package")
## [1] "GeneSelector"
Los Slots que contiene esta clase GeneRanking son los siguientes.
getSlots("GeneRanking")
## x y statistic ranking
## "matrix" "factor" "numeric" "numeric"
## pval type method
## "vector" "character" "character"
show(ordT)
## Ranking by ordinaryT,
## number of genes: 54675.
toplist(ordT)
Yi ∼ N (µi , σ 2 ),
H0 : µ 1 = . . . = µ I , (7.3)
H1 : Existe i ̸= j µi ̸= µj . (7.4)
∑
I ∑
ni
SS(Intra) = (yij − ȳi· )2
i=1 j=1
∑
I
SS(Entre) = ni (ȳi· − ȳ·· )2
i=1
SS(Entre)/(I − 1)
F =
SS(Intra)/(n − I)
Bajo la hipótesis nula de que todas las medias son la misma (y pues-
to que asumimos una misma varianza) tendríamos una distribución
común bajo todas las condiciones. Asumiendo la hipótesis nula el es-
tadístico F se distribuye como un F con I-1 y n-I grados de libertad,
F ∼ FI−1,n−I .
data(gse20986,package="tamidata")
y = exprs(gse20986)[678,]
summary(aov(y ~ pData(gse20986)[,"tissue"]))
7.9. EJERCICIOS 147
## Df Sum Sq Mean Sq
## pData(gse20986)[, "tissue"] 3 0.005309 0.001770
## Residuals 8 0.020212 0.002527
## F value Pr(>F)
## pData(gse20986)[, "tissue"] 0.7 0.578
## Residuals
library(multtest)
library(genefilter)
gse20986.aov =
rowFtests(gse20986, pData(gse20986)[,"tissue"])
head(gse20986.aov,n=2)
## statistic p.value
## 1007_s_at 9.782456 0.004715281
## 1053_at 14.144595 0.001455658
7.9 Ejercicios
Ej. 18 — Con los datos multtest::golub y utilizando las funciones
base::apply, stats::sd, stats::IQR se pide:
1.Determinar para cada gen (esto es, las expresiones de una fila
dada) el rango intercuartílico.
2.Una vez hemos calculado el rango intercuartílico para gen calcu-
lar el percentil de orden 0.50 (o mediana).
3.Determinar las filas correspondientes a los genes cuyo rango in-
tercuartílico supera el percentil que hemos calculado en el apar-
tado anterior.
6 No es la única opción. Podríamos usar una opción no paramétrica.
148 CAPÍTULO 7. EXPRESIÓN DIFERENCIAL MARGINAL
Comparaciones
múltiples
8.1 Introducción
Empezamos con algunos comentarios bibliográficos. Esta sección se
basa fundamentalmente en [40]. Sin embargo, un artículo a consultar
es [117].
Supongamos que nuestras muestras corresponden a dos grupos que
de un modo genérico podemos llamar casos y controles. Nuestro interés
no está en evaluar si uno o dos genes concretos se expresan de un modo
distinto entre las dos condiciones consideradas. Se pretende una visión
global. Pretendemos responder a una pregunta como: ¿qué genes se
expresan de un modo distinto (o diferencial en la jerga habitual en
esta literatura) en los dos grupos que consideramos? Tenemos miles
de genes: ¿cuáles de ellos tienen realmente una expresión diferencial?
Y, lo importante, pretendemos responder la pregunta de modo que
controlemos, de algún modo, las veces que admitimos una expresión
diferencial cuando no la tiene. ¿Qué contrastes de hipótesis estamos
evaluando? Si numeramos los genes con i = 1, . . . , N entonces para el
i-ésimo gen estamos considerando el contraste de hipótesis siguiente:
• Hi : El gen i no tiene una expresión diferencial entre las condi-
ciones consideradas.
• Ki : El gen i tiene una expresión diferencial entre las condiciones
consideradas.
El contraste anterior se puede reformular como
• Hi : La expresión del gen i no tiene asociación con la condición.
• Ki : La expresión del gen i tiene asociación con la condición.
1
149
150 CAPÍTULO 8. COMPARACIONES MÚLTIPLES
F W ER = P (V > 0) = P (V ≥ 1).
H0C = ∩N
i=1 Hi .
P CER ≤ F DR ≤ F W ER.
pi = P (|Ti | ≥ ti |Hi ).
que siguen se entienden que son condicionadas a que todas las hipótesis nulas son
simultáneamente ciertas. Tenemos
∑
N
i=1 Ei ) = 1 − P (∪i=1 Ei ) ≤ 1 −
P (∩N N c
P (Eic ). (8.4)
i=1
∑
N
α
i=1 Ei ) ≤ 1 −
P (∩N P (Eic ) ≤ 1 − m . (8.5)
i=1
N
8.5. MÉTODOS QUE CONTROLAN LA FWER 155
p̃i = min{N pi , 1}
data(gse1397,package ="tamidata")
eset = gse1397; y = pData(gse1397)[,"type"]
tt = genefilter::rowttests(eset,y)
p0 = tt[,"p.value"]
tt1 = data.frame(tt,p.BH)
alpha = 0.05
p1 = p.adjust(p0, "BH")
## [1] 902
8.8 El q-valor
Esta sección se basa en [133]. Supongamos que ordenamos de me-
nor a mayor los p-valores calculados para los distintos contrastes.
p(1) ≤ . . . ≤ p(N )
¿Qué es el q-valor?
Posiblemente el mejor modo de entender qué es el q-valor sea ver
un buen procedimiento para estimarlo propuesto en [133] e implemen-
tado en el paquete [9, qvalue]. Fijamos un valor t y consideremos que
rechazamos Hi cuando Pi ≤ t.9 Consideremos los siguientes valores
y
R(t) = |{Pi : Pi ≤ t; i = 1, . . . , N }| (8.7)
Se puede aproximar la pFDR con
[ ]
V (t)
E
R(t)
9 Como es habitual denotamos por P el p-valor antes de ser observado, esto es,
i
el valor aleatorio antes de tomar los datos.
8.8. EL Q-VALOR 159
P (Pi ≤ t|Hi ) = t.
Por tanto
EV (t) = N0 t.
Pero no conocemos N0 número de hipótesis nulas ciertas. Lo que
vamos a hacer es estimar la proporción de hipótesis nulas ciertas
π0 = N0 /N (notemos que el total de hipótesis, N , sí es conocido).
Bajo Hi , el p-valor aleatorio Pi es uniforme en [0, 1], por tanto los p-
valores correspondientes a hipótesis nulas ciertas se distribuyen sobre
todo el intervalo [0, 1], sin embargo, aquellos p-valores muy pequeños,
muy próximos a cero, es más probable que correspondan a hipótesis
nulas falsas. Fijamos un valor λ ∈ [0, 1], un estimador razonable para
π0 es
|{pi : pi > λ; i = 1, . . . , N }|
π̂0 = .
N (1 − λ)
Podemos pues estimar pFDR con
\ π̂0 N t
pF DR = .
|{pi : pi ≤ t}|
El q-valor asociado a un contraste sería el mínimo valor de pFDR
que se alcanza cuando el contraste es rechazado. Es decir, el q-valor
asociado al test i-ésimo sería
y su estimador sería
\
q̂(pi ) = min pF DR(t).
t≥pi
π̂0 = fˆ(1).
5. Calculamos
π̂0 N t
q̂(p(m) ) = min = π̂0 p(N ) .
t≥p(N ) |{pi : pi ≤ t}|
6. Para i = N − 1, . . . , 1 calculamos
Calculando el q-valor
El método de estimación que hemos visto en § 8.8 está implemen-
tado en el paquete [9, qvalue].10
Utilizamos los datos tamidata::gse1397.
pacman::p_load("Biobase")
data(gse1397,package="tamidata")
tt = genefilter::rowttests(gse1397,pData(gse1397)[,"type"])
pvalue = tt$p.value
pacman::p_load(qvalue)
qobj = qvalue(pvalue)
plot(qobj)
1.02 ● 5
● ●●●●
● ●
●
●
significant tests
●● 4
1.00 ●
●
^ 0(λ)
3
0.98
π
●
●
● 2
0.96
●
^ 0 = 0.955
π ● 1
0.00 0.25 0.50 0.75 1.00 0.01 0.02 0.03 0.04
λ q−value cut−off
expected false positives
0.04 0.20
0.15
q−value
0.03
0.02 0.10
0.05
0.01
0.00
0e+00 3e−06 6e−06 9e−06 1 2 3 4 5
p−value significant tests
q.value = qvalue(pvalue)$qvalues
8.9 Ejercicios
Ej. 21 — Utilizando los datos tamidata::gse20986 se pide:
1.Seleccionar las muestras correspondientes a iris y huvec.
2.Aplicamos, a cada gen, un test de la t (asumiendo una misma
varianza). Obtener los t-estadísticos y los p-valores correspon-
149
Utilizad genefil- dientes. 149
ter::rowttests. 3.Utilizando el método de corrección de Benjamini-Hochberg ob-
150
Utilizad [112, multtest]. tener los p-valores ajustados.150
4.Si utilizamos un valor de FDR igual a 0.05: ¿qué genes declara-
mos como significativos?
5.Repetir los apartados anteriores comparando los muestras co-
rrespondientes a retina y huvec.
6.Repetir los apartados anteriores comparando las muestras co-
rrespondientes a coroides y huvec.
7.Utilizando la función base::intersect y la función Biobase::featureNames
determinar los genes comunes a cada par de comparaciones y los
comunes a las tres comparaciones.
Expresión diferencial
con microarrays
9.1.1 El método
El conjunto de muestras, como es habitual, lo denotaremos como
por {1, . . . , n}. Empezamos con el caso en que pretendemos comparar
dos grupos. Esta información la podemos tener con un vector y =
(y1 , . . . , yn ) donde yj vale 1 si la muestra j está en el primer grupo y
vale 2 si la muestra en esa columna está en el segundo grupo. Para
un gen dado las expresiones del grupo 1 (o del grupo 2) corresponden
con los valores donde yj = 1 (respectivamente yj = 2). Consideramos
Jg = {j : yj = g} con g = 1, 2. Tendremos J1 y J2 donde Jg son
las muestras del grupo g con g= 1,2.2 Denotamos por n1 y n2 los
cardinales de J1 y J2 . Podemos denotar
∑
j∈Jg xij
x̄ig = x̄i,Jg =
ng
siendo ng el número de muestras en Jg . Para el i-ésimo gen conside-
ramos la diferencia relativa dada por
x̄i1 − x̄i2
di = (9.1)
si + s0
donde v
u ∑
u 2 ∑
si = ta (xij − x̄i,g )2 (9.2)
g=1 j∈Jg
163
164CAPÍTULO 9. EXPRESIÓN DIFERENCIAL CON MICROARRAYS
y
1/n1 + 1/n2
a=
n1 + n2
Observemos que el estadístico di es el estadístico del contraste de
igualdad de medias o simplemente el t-estadístico al que le modifica-
mos el error estándar. ¿Para qué se hace esta modificación? Si el valor
si es muy pequeño entonces el valor di es muy grande. En valores
de expresión pequeños esto puede pasar. Los distintos valores di no
son comparables para los distintos genes (la expresión que utilizan los
propios autores es que no son intercambiables). Por ello se le suma
un valor s0 que estabiliza la varianza (y nos permite comparar los t-
valores entre si). Este valor hay que estimarlo o calcularlo a partir de
los propios datos (§ 9.1.2). Veamos el procedimiento enumerando los
pasos.
∑
B
d(i) (b)
d¯(i) = .
B
b=1
y
l(∆) = max{di : i es significativamente negativo}
lante los valores de d son todos positivos y se trabaja con los percentiles 0 y 0.5.
166CAPÍTULO 9. EXPRESIÓN DIFERENCIAL CON MICROARRAYS
9.1.2 Cálculo de s0
La selección de s0 se hace del siguiente modo:
(a) Se calcula
1 (α)
vj = M AD({di : si ∈ [qj/100 (s), q(j+1)/100 (s)]})
0.64
para j = 1, . . . , 100 donde MAD es la mediana de las des-
viaciones absolutas respecto de la mediana (§ 20.4).
(b) Calculamos el valor CV (α), el coeficiente de variación de
151
El coeficiente de varia- los valores vj .151
ción es el cociente de la me- (c) Se elige como valor de α: α̂ que minimiza CV (α).
dia y la desviación estándar.
(d) Finalmente tomamos para s0 : ŝ0 = qα̂ (s).
pacman::p_load("samr")
data(golub,package="multtest")
fac0 = golub.cl +1
samfit = SAM(golub,fac0,resp.type="Two class unpaired",
nperms=1000,fdr.output=.001)
samfit$del
## delta
## 1.470792
(sigtabla = samfit$siggenes.table)
9.1. MÉTODO SAM 167
plot(samfit)
## pdf
## 2
con v
u ∑K
u ∑K
t k=1 nk
ri = ∏K nk (x̄i,Jk − x̄i· )2 (9.4)
k=1 nk k=1
y
v
u (∑ )∑
K ∑
u 1
K
1
si = t ∑K (xij − x̄i,Jk )2 . (9.5)
k=1 (nk − 1)
nk
k=1 k=1 j∈Jk
y
σ̂i
si = √∑ (9.7)
n
j=1 (yj − ȳ)2
donde √∑
n
j=1 (xij − x̂ij )2
σ̂i = , (9.8)
n−2
y
9.1.5 Ejercicios
Ejercicio 23
Utilizando los datos tamidata::gse20986 se pide:
Ejercicio 24
Utilizando los datos tamidata::gse20986 se pide determinar los ge-
nes significativos cuando comparamos los cuatro grupos considerados
en el estudio.
9.2 Limma
Hasta el momento nos hemos preocupado de estudiar la posible
asociación entre el perfil de expresión de un gen y una sola covariable
(o variable fenotípica). Nuestro mayor interés (aunque hemos consi-
derado otros casos sobre todo con el método SAM) ha estado en el
9.2. LIMMA 169
156
§ 27. Como es habitual en la teoría de modelos lineales156 estamos interesa-
dos en ciertos contrastes sobre el vector de coeficientes αi que corres-
ponden al diseño utilizado en la experiencia y, por lo tanto, evalúan
problemas de interés desde un punto de vista biológico. Un contraste
tiene la forma general
βi = C ′ α i .
Estamos interesados en contrastar si βij son nulas para los distintos
j y para cada gen i, es decir, en la hipótesis nula: H0 : βij = 0 vs
H0 : βij ̸= 0.
Ajustamos un modelo lineal para cada gen y obtenemos los esti-
madores α̂i , el estimador s2i de σi2 y la matriz de covarianzas estimada
β̂i = C ′ α̂i ,
y de su matriz de covarianzas es
var(β̂i ) = C ′ Vi Cs2i .
β̂ij
tij = √
si vij
β̂ij
t̃ij = √ .
s̃2i vij
P (βij ̸= 0|t̃ij,s2i )
Oij = . (9.14)
P (βij = 0|t̃ij,s2i )
siendo
d0 2
s2∗,i = s2i + s .
di 0
Cada varianza muestral es incrementada un valor positivo en princi-
pio distinto para cada gen. La idea que vimos en § 9.1 consistía en
considerar
β̂ij
t∗,ij = √
(si + a) vij
donde a es un valor positivo determinado por un método ad-hoc. En
este método lo que se incrementa es la desviación estándar y no la
varianza. El t-estadístico moderado incrementa la varianza. Además
el incremento puede ser distinto para cada gen.
¿Y si queremos contrastar más de un contraste al mismo tiempo?
En lugar de t-estadísticos moderados tendremos F-estadísticos mo-
derados. Se comprueba que los F-estadísticos moderados no son más
que los F-estadísticos usuales en los cuales sustituimos las varianzas
si2 por s̃2i . Además su distribución es Fi ∼ Fr,d0 +di , siendo r el núme-
ro de contrastes linealmente independientes. Vemos que los grados de
libertad del denominador también se incrementan.
9.2. LIMMA 173
data(gse44456,package="tamidata")
pData(gse44456)[,"postmortenint"]
Cargamos Limma.
library(limma)
head(design)
## intercept postmortenint
## 1 1 16.75
## 2 1 27.00
## 3 1 29.00
## 4 1 24.00
## 5 1 24.00
## 6 1 24.00
fit = lmFit(gse44456,design)
fit1 = eBayes(fit)
topTable(fit1,coef=2,adjust ="BH")
## logFC AveExpr t
## 7898750 -0.011508519 6.747570 -6.443278
## 8170468 0.013115884 6.012464 5.689956
## 7969651 -0.010989325 7.051056 -5.687741
## 8111415 0.008178560 2.540914 5.065649
## 7895171 0.012638970 8.895633 4.980637
## 7959012 0.012611550 4.428257 4.935664
## 7972269 -0.009755820 4.360153 -4.919346
## 8152664 -0.015744665 4.187651 -4.870722
## 7896252 -0.008523726 11.280638 -4.834066
## 7921533 -0.013989202 8.399406 -4.826789
## P.Value adj.P.Val B
## 7898750 1.016754e-07 0.003385485 6.398649
## 8170468 1.196673e-06 0.013378383 3.937214
## 7969651 1.205368e-06 0.013378383 3.930008
## 8111415 9.095965e-06 0.060272779 1.924620
## 7895171 1.195878e-05 0.060272779 1.654193
## 7959012 1.381685e-05 0.060272779 1.511583
## 7972269 1.455932e-05 0.060272779 1.459918
## 8152664 1.701344e-05 0.060272779 1.306232
## 7896252 1.912948e-05 0.060272779 1.190642
## 7921533 1.957948e-05 0.060272779 1.167723
pacman::p_load("limma")
data(gse44456,package="tamidata")
head(pData(gse44456))
## postmortenint pH
## GSM1085665_HE32H001.CEL 16.75 6.59
## GSM1085666_HE32H003.CEL 27.00 5.58
## GSM1085667_HE32H004.CEL 29.00 6.68
## GSM1085668_HE32H005.CEL 24.00 6.59
## GSM1085669_HE32H006_2_.CEL 24.00 6.53
## GSM1085670_HE32H007_2_.CEL 24.00 6.57
## batch
## GSM1085665_HE32H001.CEL Batch 1
## GSM1085666_HE32H003.CEL Batch 1
## GSM1085667_HE32H004.CEL Batch 2
## GSM1085668_HE32H005.CEL Batch 2
## GSM1085669_HE32H006_2_.CEL Batch 1
## GSM1085670_HE32H007_2_.CEL Batch 1
Ajustamos el modelo.
fit = lmFit(gse44456,design)
## Contrasts
## Levels dif
## control 1
## alcoholic -1
Estimamos.
fit2 = contrasts.fit(fit,contrast.matrix)
fit2 = eBayes(fit2)
topTable(fit2,coef=1,adjust="BH")
## logFC AveExpr t
## 7927186 -0.5424921 7.826424 -5.914411
## 8125919 -1.1358866 8.313619 -5.628792
## 8021081 -1.2885800 8.593822 -5.481851
## 7961595 0.5322101 4.180459 5.440839
## 7995838 -0.9825655 8.540374 -5.096932
## 8130867 0.5858452 7.566787 5.083113
## 8114814 0.3685955 7.694306 5.003841
## 7922889 0.5172199 8.438433 4.946850
## 8021741 0.7651623 9.183204 4.720399
176CAPÍTULO 9. EXPRESIÓN DIFERENCIAL CON MICROARRAYS
table(pData(gse44456)[,"case"],pData(gse44456)[,"gender"])
##
## male female
## control 13 6
## alcoholic 14 6
casegender = vector("list",ncol(gse44456))
for(i in seq_along(casegender))
casegender[[i]] = paste(pData(gse44456)[,"case"][i],
pData(gse44456)[,"gender"][i],sep="")
casegender = factor(unlist(casegender))
fit = lmFit(gse44456,design)
cont.matrix = makeContrasts(
dif1 = controlmale - alcoholicmale,
dif2 = controlfemale - alcoholicfemale,
dif12 = (controlmale - alcoholicmale)- (controlfemale - alcoholicfemale),
levels = design)
fit2 = contrasts.fit(fit,cont.matrix)
fit2 = eBayes(fit2)
topTable(fit2,coef=1,adjust="BH")
topTable(fit2,coef=2,adjust="BH")
topTable(fit2,coef=3,adjust="BH")
Expresión diferencial
con datos RNASeq
10.1 Introducción
Tenemos datos de expresión de gen obtenidos mediante la técnica
conocida como RNA-seq. Pero, ¿qué tenemos realmente? ¿Con qué
vamos a trabajar?
Ya hemos realizado todo el preprocesado. Ya hemos alineado y
contado lecturas a nivel de gen (o si podemos isoforma). Tenemos pues
una matriz de expresión observada x = [xij ]i=1,...,N ;j=1,...,n donde
hemos considerado N genes y tenemos n muestras. Además tendremos
covariables, variables fenotípicas o metadatos.165 Estas covariables son 165
Un estadístico dice cova-
otra matriz n × p donde n es el número de muestras y p es el número riable, un bioinformático di-
de covariables de las que disponibles sobre las muestras. Tendremos ce variable fenotípica y un
y = [yjk ]j=1,...,n;k=1,...,p . Habitualmente p = 1 y y = (y1 , . . . , yn )′ es moderno de los de los Big
simplemente un vector. Data diría cualquier cosa,
por qué no, metadatos.
179
180CAPÍTULO 10. EXPRESIÓN DIFERENCIAL CON DATOS RNASEQ
167
Que obviamente es alea- ésimo, esto es, consideramos constante el conteo xi1 + xi2 .167 El gen
torio. Trabajamos condicio- que consideramos tiene un conteo aleatorio Xi1 en la primera muestra
nados a ese valor. (por ejemplo, correspondiente a caso). Su distribución de probabili-
dad será binomial con xi1 + xi2 pruebas y una probabilidad de éxito
(lectura procedente de la primera muestra) desconocida p. Si no hay
diferencias entre las muestras el valor de p debiera de coincidir con
m1 /(m1 +m2 ), es decir, debe coincidir la proporción con la proporción
que la primera muestra representa en el total de las dos muestras. Por
tanto, evaluar la expresión diferencial del gen se traduce en un con-
traste sobre p la probabilidad de que la lectura corresponda al caso.
Una primera referencia en este sentido es [79].
En edgeR::binomTest utilizan como p-valor la suma de las proba-
bilidades de los conteos que tienen una probabilidad menor o igual al
observado bajo la hipótesis nula.
Consideremos los datos tamidata::PRJNA297664. Nos quedare-
mos con una muestra “wild” y otra “SEC66 deletion”. Compararemos
entre sí estas dos muestras.
pacman::p_load("SummarizedExperiment")
data(PRJNA297664,package="tamidata")
se = PRJNA297664
rm(PRJNA297664)
colData(se)[,"treatment"]
pacman::p_load("edgeR")
pvalor13 = edgeR::binomTest(assay(se)[,1], assay(se)[,3])
Podemos hacernos una idea de cómo son estos p-valores con una
estimación de su función de densidad con (figura ??).
También podemos aplicar para el mismo problema el test de Fis-
her. En cualquier caso, solamente tiene sentido hacer este aná-
lisis cuando tenemos una muestra en cada condición.168
¿Qué hacemos con más de una muestra? ¿Realizar todas las com-
paraciones dos a dos? No. Obviamente hay que buscar procedimientos
168
más adecuados.
Y tampoco mucho. ¿Se puede realizar algo similar cuando tenemos varias muestras
por cada una de las dos condiciones? Es tentador simplemente sumar
los conteos de cada gen en cada condición. Tendríamos el total de
lecturas por gen y condición. Sin embargo, si consideramos la tabla
10.1 correspondiente estaríamos ignorando la variabilidad intra con-
dición de los conteos correspondientes. En este caso hemos de acudir
a alguno de los procedimientos que vemos en la siguientes secciones.
pares = rbind(c(1,3),c(1,5),c(1,6),c(2,3),c(2,5),c(2,6),c(4,3),
c(4,5),c(4,6))
aux = function(rr) binomTest(assay(se)[,rr[1]], assay(se)[,rr[2]])
pvalores = apply(pares,1,aux)
png("figures/RNASeqDE10.png")
pvalores.mean = apply(pvalores,1,mean) ## Media de p-valores
pvalores.min = apply(pvalores,1,min) ## Mínimo de p-valores
pvalores.max = apply(pvalores,1,max) ## Máximo de p-valores
df = data.frame(pvalores.mean,pvalores.min,pvalores.max)
df=df[sort(pvalores.mean,index.return=TRUE)$ix,] ## Ordenamos
df1 = reshape2::melt(df,id="pvalores.mean")
pp = ggplot(df1,aes(x=pvalores.mean,y=value,color=variable))
pp + geom_smooth() # Suavizamos mínimo y máximo
dev.off()
10.3 edgeR
Este paquete implementa los procedimientos propuestos en [122,
121]169
169
Hay que leer primero
10.3.1 Estimación de una dispersión común [122] y luego [121] pues es
la secuencia temporal de los
Consideramos una característica en n muestras (o librerías) de trabajos aunque se publica-
tamaños distintos.170 Sea mi el tamaño de la i-ésima librería (total de ron en orden invertido.
lecturas). Sea λ la proporción que hay en una librería cualquiera de 170
Son réplicas de una mis-
la característica en que estamos interesados. Vamos a asumir que Yi ma experimentación con ta-
tiene una distribución binomial negativa con media µi = mi λ y con maños distintos.
dispersión ϕ. Y tiene una distribución binomial negativa con media µ y
dispersión ϕ, Y ∼ BN (µ, ϕ), si su función de probabilidad es P (Y =
( )ϕ−1 ( )y
Γ(y+ϕ−1 ) 1 µ
y|µ, ϕ) = Γ(ϕ−1 )Γ(y+1) 1+µϕ ϕ−1 +µ para y = 0, 1, . . .. Su
media es E(Y ) = µ y su varianza var(Y ) = µ + ϕµ2 . Ver § 21.8.2.
Supongamos el caso ideal (e irreal) en que todas las librerías tienen
el mismo tamaño:
∑n mi = m para i = 1, . . . , n. Bajo esta condición tene-
mos que Z = i=1 Yi ∼ N B(nmλ, ϕ/n). Además la logverosimilitud
182CAPÍTULO 10. EXPRESIÓN DIFERENCIAL CON DATOS RNASEQ
2 (∑
∑ nj
li (ϕ) = log Γ(yijk + ϕ−1 ) + log Γ(nj ϕ−1 )−
j=1 k=1
)
−1 −1
log Γ(zij + nj ϕ ) − nj log Γ(ϕ ) . (10.3)
Hi : λi1 = λi2 ,
Ki : λi1 ̸= λi2 .
EYijk = m∗ λij ,
Bajo la hipótesis
∑nj nula de no diferencia entre grupos tendríamos
∗
que Yij· = k=1 Yijk ∼ N B(nj m λ̂i , ϕ̂C /nj ) para j = 1, 2. Ade-
más Yi1· e Yi2· son independientes. La suma Yi1· +∑ Yi2· también
∑nj tiene
2
una distribución binomial negativa: Yi1· + Yi2· = i=1 k=1 Yijk ∼
N B((n1 + n2 )m∗ λ̂i , ϕ̂C /(n1 + n2 )). Podemos considerar la distribu-
ción condicionada del vector aleatorio (Yi1· , Yi2· ) a la suma Yi1· +Yi2· y
considerar las probabilidades de los conteos conjuntos que son menos
probables que el observado. La suma de estas probabilidades nos daría
174
Es un test similar al el p-valor del test.174
test de Fisher bilateral en
donde las probabilidades hi-
pergeométricas son sustitui- 10.3.3 Dispersiones posiblemente distintas
das por probabilidades por la En el test exacto que hemos visto en § 10.3.2 hemos asumido una
distribución binomial negati- dispersión común ϕ y se ha estimado su valor utilizando los conteos
va. Ver [3, Página 93]. asociados a todos los genes y condiciones bajo las cuales se han ob-
servado a estos genes. Bajo la hipótesis nula de un misma media, y
asumiendo la dispersión común esto tenía sentido. Es, sin duda, una
hipótesis bastante exigente. Una misma dispersión sobre una cantidad
175
Buena desde el punto de grande de genes no es muy razonable.175 En [121] proponen no asumir
vista del modelo y su estima- un mismo valor para cada gen y considerar que las dispersiones de-
ción pero nos aleja de los da- penden del gen. Tenemos ahora, en lugar del valor común ϕ, un valor
tos. (posiblemente) distinto para el gen i, ϕi . ¿Y cómo lo estimamos? Pro-
ponen un compromiso entre la contribución que hacen los conteos del
i-ésimo gen, li (ecuación 10.3), a la logverosimilitud global, l (ecua-
ción 10.4), y la propia logverosimilitud global. En concreto hablan de
la logverosimilitud condicionanda ponderada definida como
∂ 2 li (ϕ)
Ii (ϕ) = E(Ji ), siendo Ji = − . (10.7)
∂ϕ2
data(PRJNA297664,package="tamidata")
pacman::p_load("edgeR","SummarizedExperiment")
dge = DGEList(counts=assay(PRJNA297664),
group=colData(PRJNA297664)[,"treatment"])
dge.c = estimateCommonDisp(dge) ##Estimamos dispersión común
dge.c$common.dispersion
## [1] 0.01170892
topTags(et.c)
topTags(et.t)
10.5 SAMseq
Este método fue propuesto en [85] y está implementado en el pa-
quete [138, samr]. Supongamos el caso con dos grupos. Denotamos
como siempre por xij el conteo de la i-ésima característica en la j-
ésima muestra (i = 1, . . . , N y j = 1, . . . , n). El tamaño de la librería
∑N
o profundidad de secuenciación será mj = j=1 xij . Como siempre el
10.5. SAMSEQ 187
′
lidad 1 − mj . Si denotamos por Xij el número de lecturas que nos
m0
′ m0
Xij |Xij ∼ Binomial(Xij , ).
mj
Los autores llaman a esto un muestreo hacia abajo.180 Este pro- 180
Down sampling.
cedimiento de muestreo nos produce unos nuevos conteos y un nuevo
valor del estadístico dado en 10.8 que podemos denotar por Ti′ . Note-
mos que si el tamaño mínimo es mucho menor que el resto de tamaños
estamos descartando muchas lecturas.
Una segunda opción es igualar los tamaños de las librerías a un
( )1/n
∗
∏n
valor intermedio como la media geométrica m = j=1 mj .
Generamos conteos aleatorios con
( )
′ m∗
Xij |Xij ∼ P oisson Xij . (10.9)
mj
188CAPÍTULO 10. EXPRESIÓN DIFERENCIAL CON DATOS RNASEQ
Sería el muestreo Poisson. Para evitar empates entre los valores gene-
rados se sustituyen estos valores por
′
Xij + ϵij
1 ∑ ′
B
Ti∗ = Ti (b). (10.10)
B
b=1
1 ∑∑
N S
V̂ = 1|T ∗ (s)|>c (10.11)
S i=1 s=1 i
\ π̂0 V̂
F DR(c) = . (10.13)
R̂
183
O proporción de caracte- donde π0 es la proporción de hipótesis nulas ciertas.183 El esti-
rísticas que no son significa- mador de π0 utilizado es
tivamente distintas entre los ∑N
dos grupos que comparamos. 2 i=1 1|Ti∗ |≤q
π̂0 = ,
N
siendo q la mediana de {|Ti∗ (s)| : i = 1, . . . , N ; s = 1, . . . , S}.
pacman::p_load("SummarizedExperiment","samr")
data(PRJNA297664,package="tamidata")
print(PRJNA297664samseq)
plot(PRJNA297664samseq)
10.6 DESeq2
Este método se propuso en [90]. Figura 10.1: Genes significativos
con los datos PRJNA297664.
10.6.1 Método
Como es habitual en el texto denotamos la matriz de conteos alea-
toria con X donde el elemento en posición (i, j) es el conteo aleatorio
Xij correspondiente al i-ésimo gen y a la j-ésima muestra. Se asume
que Xij sigue una distribución binomial negativa (§ 21.8.2) con media
µij y dispersión αi . Se supone que la media de este conteo aleatorio
la podemos expresar como
186 186
Un detalle importante so-
′ bre la codificación de un fac-
Los contrastes vendrán dados por c βi . El error estándar √ (su des-
viación típica) del contraste c′ βi viene dada por SE(c′ βi ) = c′ Σi c, tor. No se utilizan las habi-
donde Σi denota la matriz de covarianzas de βi . Cuando se contraste tuales variables dummy que
si estos contrastes187 son nulos se utiliza la matriz de diseño estándar codifican uno para una cate-
en donde no se introduce el parámetro adicional que hemos comentado goría y cero para las demás
anteriormente. Esta sí es una matriz de rango completo por columnas. dejando la media como el va-
lor en una categoría de re-
ferencia. Los autores utilizan
un parámetro para la media
y una variable dummy por
cada nivel del factor expe-
190CAPÍTULO 10. EXPRESIÓN DIFERENCIAL CON DATOS RNASEQ
1 ∑ xij
n
µ̄i = . (10.16)
n j=1 sij
log ϕgw
i − log ϕ̃(µ̄i ).
slr =
1
M AD({log ϕgw
i − log ϕ̃(µ̄i ) : i = 1, . . . , N }). (10.19)
Φ−1 ( 34 )
Finalmente, la varianza de la distribución a priori es estimada
con
σd2 = max{s2lr − ψ1 ((n − p)/2), 0.25}, (10.20)
donde ψ1 es la función trigamma; n, el número de muestras y p
el número de covariables por muestra.
El estimador 10.20 no es adecuado cuando los grados de libertad
residuales (número de muestras n menos número de parámetros
a estimar p) son de tres o inferior. En este caso se propone un
método basado en simulación que se puede consultar en [90, pág.
16].
Estimaciones de la dispersión. El estimador final de la dispersión
ϕi se obtiene
( ( ) )
ϕM
i
AP
= argmax ϕ lCR ϕ; µ̄ 0
i· , x i· + Λ i (ϕ) (10.21)
siendo
−(log ϕ − log ϕ̃(µ̄i ))2
Λi (ϕ) = .
2σd2
Outliers de dispersion. En el punto anterior hemos indicado cómo
estimamos la dispersión para cada gen. No obstante, si un gen
verifica que
log ϕgw
i > log ϕ̃(µ̄i ) + 2slr
entonces consideramos el gen como un outlier en términos de
dispersión. Para estos genes utilizamos como estimador de su
dispersión no el propuesto en el apartado anterior sino ϕgw
i .
Además estos genes no son utilizados cuando ajustamos ϕ̃.
192CAPÍTULO 10. EXPRESIÓN DIFERENCIAL CON DATOS RNASEQ
Estimadores de βi .
Se estima βi como el valor que maximiza
∑
n
fN B (xij |µj (β), ϕi ) + Λ(β) (10.23)
j=1
siendo ∑p
yjr βr
µj (β) = sij e r=1 ,
∑
p
−β 2 r
Λ(β) = ,
r=1
2σr2
y ϕi = ϕMi
AP
excepto para los genes que son outliers de dispersión
en donde ϕi = ϕgw i . La función 10.23 es maximizada utilizando el
algoritmo de regresión ridge iterativamente reponderada. En concreto
en una iteración dada actualizamos los valores de los coeficientes con
β ← (D′ W D + λI)−1 D′ W z,
1
donde λr = σr2 y
µj xj − µ j
zj = log +
sj µj
∑p
siendo µj (β) = sj e r=1 yjr βr donde los valores de βr son la estimación
en la iteración actual.
10.6.2 Paquete
Vamos a analizar los datos tamidata2::PRJNA218851.
pacman::p_load(SummarizedExperiment,DESeq2)
data(PRJNA218851,package="tamidata2")
dds = DESeq(dds)
10.8 Ejercicios
Ej. 25 — Para los datos tamidata::PRJNA297664 se pìde:
1.Aplicar el procedimiento de comparación de proporciones utili-
zando edgeR::binomTest a las muestras 1 y 3.
2.Ajustar los p-valores obtenidos en el punto anterior por el método
de Benjamini-Hochberg.
3.Una vez ajustados los p-valores determinar cuantos y cuales tie-
nen un p-valor ajustado menor a 0.01.
4.Repetir los tres pasos anteriores comparando las muestras 2 y 5.
5.¿Cuántos genes han sido detectados como significativos simultá-
neamente en los puntos 3 y 4?
Tamaño muestral y
potencia
195
196 CAPÍTULO 11. TAMAÑO MUESTRAL Y POTENCIA
Capítulo 12
Generando un informe
library(Biobase)
data(gse20986,package="tamidata")
eset = gse20986
library(genefilter)
library(multtest)
eset = gse20986[, c(2, 3, 5, 10:12)]
tissue = factor(rep(1:2, each = 3), levels = 1:2,
labels = c("retina", "huvec"))
tt = rowttests(eset, tissue)
1 Que esperemos no sea Internet Explorer.
197
198 CAPÍTULO 12. GENERANDO UN INFORME
head(sig)
El número de significativos es
nsig = length(sig)
pvalor = p.BH$adjp[1:nsig,1]
pajustado = p.BH$adjp[1:nsig,2]
library(annotate)
annotation(eset)
## [1] "hgu133plus2"
library(hgu133plus2.db)
ID = featureNames(eset)[sig]
head(ID)
¿O en Gene Ontology?
ls("package:hgu133plus2.db")
12.2 R2HTML
Veamos cómo hacerlo con el paquete [84, R2HTML].
library(R2HTML)
ID = featureNames(eset)[sig]
Symbol = getSYMBOL(ID,"hgu133plus2.db")
Name = as.character(lookUp(ID, "hgu133plus2.db", "GENENAME"))
Ensembl = as.character(lookUp(ID, "hgu133plus2.db", "ENSEMBL"))
entrezid = as.character(lookUp(ID, "hgu133plus2.db", "ENTREZID"))
Podemos tener campos vacíos que hay que declarar como datos
faltantes.
tmp[tmp=="NA"] = NA
HTML(tmp,"reports/prueba.html",append=F)
browseURL("reports/prueba.html")
browseURL("reports/prueba.html")
12.3 ReportingTools
En esta sección vemos cómo generar un informe con [67, Repor-
tingTools]. Cargamos el paquete.
library(ReportingTools)
ID = featureNames(eset)[sig]
Name = as.character(lookUp(ID,"hgu133plus2.db", "GENENAME"))
entrezid = as.character(lookUp(ID, "hgu133plus2.db", "ENTREZID"))
ID[ID == "NA"] = NA
Name[Name == "NA"] = NA
entrezid = ifelse(entrezid == "NA",NA,
paste("<a href='http://www.ncbi.nlm.nih.gov/gene/?term=",
entrezid,"'>",entrezid,"</a>",sep=""))
2 Crucemos los dedos para que no sea Internet Explorer.
12.4. EJERCICIOS 201
foutput = "gse20986.DE"
htmlRep1 = HTMLReport(shortName = foutput,title = foutput,
reportDirectory = "./reports")
publish(df,htmlRep1)
finish(htmlRep1)
## [1] "./reports/gse20986.DE.html"
12.4 Ejercicios
Ejercicio 26
Utilizando el ExpressionSet gse1397 se pide:
1. ¿Cuál es el chip utilizado?
2. Seleccionar el gen en la fila 678. ¿Cuál es su identificador Affy-
metrix, AffyID? Determinar los identificadores en las siguientes
bases de datos: Ensembl, Gene Ontology y NCBI.
3. Elegir al azar 100 genes con la función sample. Determinar sus
AffyIDs y los correspondientes en Ensembl, Gene Ontology y
NCBI.
Reducción de dimensión
y clasificación
203
Capítulo 13
Componentes
principales
13.1 Introducción
En este tema nos ocupamos de problemas de reducción de dimen-
sión. ¿Qué significa reducir la dimensión? Responder a esta pregunta
es obvio si nos fijamos en los datos que tenemos. Trabajando con ex-
presión de genes tenemos tantas filas como genes y tantas columnas
como muestras. En resumen miles de filas y decenas o centenares de
columnas. En el tema En temas anteriores hemos visto como seleccio-
nar filas, esto es, seleccionar genes es una tarea incluso previa. Hemos
de quedarnos con genes que tengan una expresión diferencial si consi-
deramos alguna característica fenotípica o bien con genes que tengan
una expresión mínima o bien con genes que tengan un cierto nivel de
variación. ¿Qué hacemos con las columnas? O de otro modo: ¿qué ha-
cemos con las muestras? Quizás la respuesta natural sería: si tenemos
miles de filas, ¿por qué preocuparse de unas decenas de filas? No es
una buena respuesta. Realmente tener 50 o 100 columnas son muchas
a la hora de visualizar resultados o bien de aplicar tratamientos es-
tadísticos. En este tema tratamos el tema de cómo reducir el número
de columnas o el número de filas.
data(golub,package="multtest")
sel = grep("Cyclin",golub.gnames[,2])
golub.red = golub[sel,1:2]
pacman::p_load("ggplot2")
df = data.frame(golub.red)
names(df) = c("sample1","sample2")
205
206 CAPÍTULO 13. COMPONENTES PRINCIPALES
png(paste0(dirTamiFigures,"PCA2.png"))
ggplot(df,aes(x=sample1,y=sample2)) + geom_point()
dev.off()
medias = colMeans(golub.red)
medias = apply(golub.red,2,mean)
golub.red = sweep(golub.red,2,medias)
colMeans(golub.red)
Figura 13.2: a) Centramos los datos golub.red y mostramos el nuevo sistema de coordenadas en rojo. b) Vectores que
definen las líneas donde proyectamos. c) Las líneas sobre las que proyectamos. d) Datos golub.red mostrando las líneas
sobre las que proyectamos (en azul) para obtener las dos componentes principales y las proyecciones sobre la primera
componente en verde. e) Datos golub.red mostrando las líneas sobre las que proyectamos (en azul) para obtener las
dos componentes principales y las proyecciones sobre la segunda componente.
a.pca = prcomp(golub.red)
a.pca$rotation
## PC1 PC2
## [1,] -0.7619878 0.6475914
## [2,] -0.6475914 -0.7619878
colMeans(golub.red)
1∑
n
(ui − ū)2 .
n i=1
a.pca = prcomp(golub.red)
a.pca$rotation
## PC1 PC2
## [1,] -0.7619878 0.6475914
## [2,] -0.6475914 -0.7619878
predict(a.pca)
## PC1 PC2
## [1,] -2.50309193 -1.541823e-01
## [2,] 0.01368602 -2.024163e-01
## [3,] -2.38702381 3.714339e-03
## [4,] 0.33489688 -6.847077e-05
## [5,] 0.76608286 2.806154e-01
## [6,] 0.27144878 2.899820e-02
## [7,] 0.31169639 -2.876394e-01
## [8,] 2.22052303 -8.232084e-02
## [9,] -0.93221244 1.836866e-01
## [10,] -0.39946389 -7.239549e-03
13.3. COMPONENTES PRINCIPALES DE LOS DATOS GOLUB209
a.pca$sdev^2
var(golub.red[,1])
## [1] 1.266931
var(golub.red[,2])
## [1] 0.9245807
cuya suma es
var(golub.red[,1]) + var(golub.red[,2])
## [1] 2.191512
sum(a.pca$sdev^2)
## [1] 2.191512
variacion.total = sum(a.pca$sdev^2)
a.pca$sdev^2 / variacion.total
de datos completo: todos los datos golub que tienen 38 muestras (27
de un tipo de leucemia y 11 de otro tipo).
Obtengamos las componentes principales.
golub.pca = prcomp(golub,scale=FALSE,center=TRUE)
summary(golub.pca)
## Importance of components:
## PC1 PC2 PC3
## Standard deviation 5.0436 1.44073 1.11734
## Proportion of Variance 0.6694 0.05462 0.03285
## Cumulative Proportion 0.6694 0.72405 0.75691
## PC4 PC5 PC6
## Standard deviation 1.03505 0.85821 0.74399
## Proportion of Variance 0.02819 0.01938 0.01457
## Cumulative Proportion 0.78510 0.80448 0.81905
## PC7 PC8 PC9
## Standard deviation 0.72104 0.69232 0.63819
## Proportion of Variance 0.01368 0.01261 0.01072
## Cumulative Proportion 0.83273 0.84534 0.85606
## PC10 PC11 PC12
## Standard deviation 0.63630 0.56700 0.55263
## Proportion of Variance 0.01065 0.00846 0.00804
## Cumulative Proportion 0.86672 0.87518 0.88321
## PC13 PC14 PC15
## Standard deviation 0.53868 0.52011 0.49568
## Proportion of Variance 0.00764 0.00712 0.00647
## Cumulative Proportion 0.89085 0.89797 0.90443
## PC16 PC17 PC18
## Standard deviation 0.48402 0.47719 0.47068
13.3. COMPONENTES PRINCIPALES DE LOS DATOS GOLUB211
a = predict(golub.pca)
a[1,]
a = a[,1:5]
png(paste0(dirTamiFigures,"PCA28.png"))
df = data.frame(PC1 = a[,1],PC2=a[,2])
ggplot(df,aes(x=PC1,y=PC2)) + geom_point()
dev.off()
golub.pca$rotation[,1]
Figura 13.3: Dos primeras compo-
nentes principales de los datos go-
## [1] 0.1715179 0.1690829 0.1650131 0.1726783
lub.
## [5] 0.1659431 0.1668800 0.1686381 0.1602445
## [9] 0.1648769 0.1687936 0.1653992 0.1694389
## [13] 0.1629073 0.1661268 0.1647691 0.1720833
## [17] 0.1559293 0.1600159 0.1677201 0.1491867
## [21] 0.1272725 0.1620961 0.1643597 0.1652554
## [25] 0.1659262 0.1690494 0.1539691 0.1689052
## [29] 0.1541333 0.1516988 0.1691436 0.1682306
## [33] 0.1452419 0.1675335 0.1638384 0.1508645
## [37] 0.1476137 0.1520465
golub.pca$rotation[,2]
tgolub.pca = prcomp(t(golub),scale=FALSE,center=TRUE)
summary(tgolub.pca)
## Importance of components:
## PC1 PC2 PC3
## Standard deviation 13.0934 10.17462 9.40357
## Proportion of Variance 0.1645 0.09934 0.08485
## Cumulative Proportion 0.1645 0.26385 0.34870
214 CAPÍTULO 13. COMPONENTES PRINCIPALES
library(affycoretools)
png(paste0(dirTamiFigures,"PCA34-a.png"))
affycoretools::plotPCA(golub,legend = FALSE)
dev.off()
png(paste0(dirTamiFigures,"PCA34-b.png"))
affycoretools::plotPCA(t(golub),legend = FALSE)
dev.off()
194
Realmente si no tipi-
simplemente.
ficamos y simplementamos
centramos los datos esta-
mos realizando un análisis de
componentes principales so-
bre la matriz de covarianzas.
Si tipificamos las variables
216 CAPÍTULO 13. COMPONENTES PRINCIPALES
13.6 Ejemplos
Ejemplo 13.2 (GSE20986) Cargamos los datos.
pacman::p_load(Biobase)
data(gse20986,package="tamidata")
pData(gse20986)[,"tissue"]
png(paste0(dirTamiFigures,"PCA44.png"))
plotPCA(gse20986,
groups = pData(gse20986)[,"tissue"],
groupnames=c("iris","retina","choroides","huvec"))
dev.off()
## Importance of components:
## PC1 PC2 PC3
## Standard deviation 64.0229 58.2172 32.70628
## Proportion of Variance 0.3537 0.2924 0.09229
## Cumulative Proportion 0.3537 0.6461 0.73835
## PC4 PC5 PC6
## Standard deviation 27.38208 24.78294 21.58365
## Proportion of Variance 0.06469 0.05299 0.04019
## Cumulative Proportion 0.80304 0.85604 0.89623
## PC7 PC8 PC9
## Standard deviation 18.60356 17.9181 15.86741
## Proportion of Variance 0.02986 0.0277 0.02172
## Cumulative Proportion 0.92609 0.9538 0.97551
## PC10 PC11
## Standard deviation 13.42905 10.17363
## Proportion of Variance 0.01556 0.00893
13.6. EJEMPLOS 217
df0 = t(exprs(gse20986))
tissue = pData(gse20986)[,"tissue"]
df = data.frame(tissue,df0)
pacman::p_load(ggfortify)
png(paste0(dirTamiFigures,"PCA46b.png"))
autoplot(prcomp(df[,-1]),data=df,colour="tissue")
dev.off()
data(gse1397,package="tamidata")
pData(gse1397)[,'type']
pData(gse1397)[,'tissue']
png(paste0(dirTamiFigures,"PCA51.png"))
affycoretools::plotPCA(gse1397, groups = pData(gse1397)[,'type'],
groupnames = levels(pData(gse1397)[,'type']))
dev.off()
T ′ ΣT = Λ = diag(λ1 , . . . , λd ), (13.1)
Demostración.
En cuanto al apartado primero tenemos que
Análisis cluster
14.1 Introducción
Este tema está dedicado al análisis cluster y su aplicación a datos
de expresión de gen. Trataremos lo que en la literatura estadística
recibe el nombre de análisis cluster1 o, en mejor castellano, análisis
de conglomerados. En la literatura de Inteligencia Artificial se utiliza
la expresión clasificación no supervisada.2
¿Qué vamos a clasificar cuando trabajamos con datos de expre-
sión de gen? Nuestra información es la matriz de expresión. Podemos
considerar como observaciones a clasificar los genes. En este caso, la
observación son los niveles de expresión observados en todas las mues-
tras, el perfil de expresión del gen sobre las muestras analizadas.
También podemos considerar como observaciones a clasificar las
muestras. En este caso cada muestra viene descrita por sus expresiones
sobre todos los genes. Podemos trabajar con todos los genes o con un
subconjunto de genes.
En uno u otro caso tenemos una muestra de observaciones multiva-
riantes de dimensión d. ¿Qué pretendemos hacer con ellos? Encontrar
grupos. Muy breve la respuesta pero: ¿qué son grupos? Imaginemos
una imagen aérea fija de un patio de un colegio. En esta imagen los
datos son las posiciones de los niños. ¿Se agrupan los niños formando
grupos o todos están jugando con todos y los grupos son una conse-
cuencia pasajera del juego (delanteros y defensas que aparecen agru-
pados en un ataque)?
Parece claro y simple el problema. Sí, lo parece. ¿Qué es un gru-
po? ¿Cómo defino un grupo? ¿Cuántos grupos distingo en los datos?
Estamos viendo el efecto del ruido o realmente hay una estructura
debajo que la vemos en un entorno con ruido.
¿Qué quiere decir encontrar grupos? Se trata de clasificar las ob-
servaciones en grupos de modo que las observaciones de un mismo
grupo sean lo más similares que podamos y que los grupos entre sí
sean muy distintos. El número de procedimientos que se han propues-
to en la literatura es muy grande. La mayor parte de ellos no tienen
un modelo probabilístico debajo, no son procedimientos basados en
modelo. Son métodos que esencialmente utilizan el concepto de proxi-
midad. Valoran de distintas formas lo próximos, lo cercanos que están
1 Porcierto que la palabra cluster no existe en castellano
2 Portradición, utilizaremos la expresión de análisis cluster. Es la que, perso-
nalmente, prefiero.
221
222 CAPÍTULO 14. ANÁLISIS CLUSTER
14.2 Datos
En esta sección presentamos tres ejemplos sencillos de observacio-
nes a agrupar y que utizamos como ilustración simple de los métodos
que proponemos.
pacman::p_load(cluster)
data(ruspini)
pacman::p_load(ggplot2)
png(paste0(dirTamiFigures,"Cluster2.png"))
ggplot(ruspini,aes(x=x,y=y))+geom_point()
dev.off()
## pdf
## 2
data(golub,package="multtest")
## [1] 1042
grep("Zyxin",golub.gnames[,2])
## [1] 2124
cz.data = data.frame(golub[1042,],golub[2124,])
names(cz.data) = c("CCND3_Cyclin_D3","Zyxin")
png(paste0(dirTamiFigures,"Cluster6b.png"))
ggplot(cz.data,aes(x=CCND3_Cyclin_D3,y=Zyxin))+geom_point()
dev.off()
## pdf
## 2
data(golub,package="multtest")
x = apply(golub[,golub.cl == 0],1,mean)
y = apply(golub[,golub.cl == 1],1,mean)
sel = grep("Cyclin",golub.gnames[,2])
golub.gnames[sel,2]
cyclin.data = data.frame(x[sel],y[sel])
names(cyclin.data) = c("meanALL","meanAML")
png(paste0(dirTamiFigures,"Cluster14.png"))
ggplot(cyclin.data,aes(x=meanALL,y=meanAML))+geom_point()
dev.off()
## pdf
## 2
14.3 Disimilaridades
Figura 14.3: Datos cyclin.data.
En lo que sigue denotaremos los datos a agrupar con xi con i =
1, . . . n siendo xi ∈ Rd . Todos los ejemplos que hemos visto en la
sección anterior eran (con objeto de poder representarlos) datos bidi-
mensionales, d = 2.
∑
d
dM (x, y) = |xk − yk |. (14.2)
k=1
5
De un modo similar podemos definir disimilaridades sustituyendo el
coeficiente de correlación de Pearson con el coeficiente de correlación
de Spearman.
d(xi , xj ) = d(xj , xi ),
D = [d(xi , xj )]i,j=1,...,n
5 En http://research.stowers-institute.org/efg/R/Visualization/
cor-cluster/ podemos encontrar un breve estudio comparativo del funcio-
namiento de estas disimilaridades en clustering jerárquico.
14.4. DISIMILARIDADES ENTRE GRUPOS DE OBSERVACIONES 227
cz.dist.euclidea = dist(cz.data,method="euclidian")
class(cz.dist.euclidea)
## [1] "dist"
cz.dist.manhattan = dist(cz.data,method="manhattan")
data(golub,package="multtest")
golub.cor1 = 1-cor(t(golub))
golub.cor2 = (1-cor(t(golub)))/2
golub.cor3 = 1-abs(cor(t(golub)))
golub.cor4 = sqrt(1-cor(t(golub))^2)
golub.cor1 = as.dist(golub.cor1)
golub.cor2 = as.dist(golub.cor2)
golub.cor3 = as.dist(golub.cor3)
golub.cor4 = as.dist(golub.cor4)
pacman::p_load(cluster)
ruspini.ag = agnes(ruspini,metric = "euclidean",method="average")
dd = dist(ruspini,method="euclidian")
ruspini.ag = hclust(dd,method="average")
png(paste0(dirTamiFigures,"Cluster23.png"))
ggdendro::ggdendrogram(ruspini.ag)
dev.off()
## pdf
## 2
230 CAPÍTULO 14. ANÁLISIS CLUSTER
cutree(ruspini.ag,4)
## 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
## 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
## 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2
## 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
## 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3
## 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
## 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4
## 65 66 67 68 69 70 71 72 73 74 75
## 4 4 4 4 4 4 4 4 4 4 4
png(paste0(dirTamiFigures,"Cluster26.png"))
p = ggplot(ruspini,aes(x=x,y=y,color=cutree(ruspini.ag,4)))
p + geom_point(shape=cutree(ruspini.ag,4))
dev.off()
## pdf
## 2
pacman::p_load(ggdendro)
png(paste0(dirTamiFigures,"Cluster29.png"))
ggdendro::ggdendrogram(cz.ag , rotate = FALSE, size = 2)
dev.off()
## pdf
## 2
cutree(cz.ag,5)
Figura 14.6: Dendograma para da-
## [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 tos cz.data utilizando distancia
euclídea y enlace simple.
## [24] 1 1 1 1 3 4 3 3 3 3 3 5 3 3 3
232 CAPÍTULO 14. ANÁLISIS CLUSTER
png(paste0(dirTamiFigures,"Cluster32.png"))
p = ggplot(cz.data,aes(x=CCND3_Cyclin_D3,y=Zyxin,color=cutree(cz.ag,5)))
p + geom_point(shape=cutree(cz.ag,5))
dev.off()
## pdf
## 2
cyclin.cofe = cophenetic(cyclin.ag)
cor(cyclin.manhattan,cyclin.cofe)
## [1] 0.8501727
ruspini.km = kmeans(ruspini,4)
ruspini.km$cluster
## 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
## 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
## 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4
## 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
## 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2
## 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
## 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1
## 65 66 67 68 69 70 71 72 73 74 75
## 1 1 1 1 1 1 1 1 1 1 1
cz.km = kmeans(cz.data,2)
cz.km$cluster
## [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [24] 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
pacman::p_load(factoextra)
png(paste0(dirTamiFigures,"Cluster50.png"))
fviz_cluster(cz.km,cz.data, ellipse.type = "norm")
dev.off()
## pdf
## 2
cz.km = kmeans(cz.data,3)
Figura 14.8: Clasificación obteni- png(paste0(dirTamiFigures,"Cluster52.png"))
da utilizando el método de las fviz_cluster(cz.km,cz.data, ellipse.type = "norm")
k-medias aplicada a los datos dev.off()
cz.data.
## pdf
## 2
14.8. SILUETA 235
ruspini.pam = pam(ruspini,4)
cz.pam = pam(cz.data,2)
png(paste0(dirTamiFigures,"Cluster58.png"))
fviz_cluster(cz.pam,cz.data, ellipse.type = "norm")
dev.off()
## pdf
## 2
14.8 Silueta
Veamos cómo se construye la silueta. Para la observación i y el Figura 14.10: Clasificación de los
grupo C consideramos datos cz.data con método PAM y
∑ dos grupos.
¯ C) = 1
d(i, d(xi , xj ),
|C|
j∈C
236 CAPÍTULO 14. ANÁLISIS CLUSTER
¯ B) = b(i) se
El grupo B donde se alcanza este mínimo, es decir, d(i,
6
le llama vecino del objeto i. Definimos s(i) como
a(i)
s(i) = 1 − si a(i) < b(i), (14.6)
b(i)
= 0 si a(i) = b(i), (14.7)
b(i)
= − 1 si a(i) > b(i). (14.8)
a(i)
Esto se puede expresar en una única ecuación como
b(i) − a(i)
s(i) = .
max{a(i), b(i)}
En el caso en que el grupo A contenga un único objeto no está muy
claro cómo definir a(i). Tomaremos s(i) = 0 que es una elección arbi-
traria. Se comprueba con facilidad que −1 ≤ s(i) ≤ 1 para cualquier
objeto i.
Para interpretar el significado de s(i) es bueno ver los valores ex-
tremos. Si s(i) es próximo a uno significa que a(i) es mucho menor
que b(i) o lo que es lo mismo, que el objeto i está bien clasificado pues
la disimilaridad con los de su propio grupo es mucho menor que la
disimilaridad con los del grupo más próximo que no es el suyo. Un
valor próximo a cero significa que a(i) y b(i) son similares y no te-
nemos muy claro si clasificarlo en A o en B. Finalmente un valor de
s(i) próximo a −1 significa que a(i) es claramente mayor que b(i). Su
disimilaridad media con B es menor que la que tiene con A. Estaría
mejor clasificado en B que en A. No está bien clasificado.
Los valores de s(i) aparecerán representados para cada cluster en
orden decreciente. Para cada objeto se representa una barra horizontal
con longitud proporcional al valor s(i). Una buena separación entre
grupos o cluster viene indicada por unos valores positivos grandes de
s(i). Además de la representación gráfica se proporciona un análisis
descriptivo. En concreto la media de los valores de la silueta dentro de
cada cluster y la media de la silueta para todo el conjunto de datos. La
clasificación será tanto mejor cuanto mayor sean estos valores medios.
De hecho, se puede decidir el número de grupos en función del valor
medio de las silueta sobre toda la muestra. Vamos probando distintos
números de grupos y nos quedamos con el número que nos da la silueta
media máxima.
¿Cuándo podemos decir que hay estructura de grupos en los datos
que estamos analizando? Experiencias con datos sugieren la tabla 14.1.
SC Interpretación
0.71 − 1.00 Fuerte estructura
0.51 − 0.70 Estructura razonable
0.26 − 0.50 Estructura débil. Probar otros métodos
≤ 0.25 No se encuentra estructura
ruspini.pam = pam(ruspini,4)
summary(silhouette(ruspini.pam))
png(paste0(dirTamiFigures,"Cluster63.png"))
fviz_silhouette(ruspini.pam)
dev.off()
## pdf
## 2
14.10 Ejemplos
En esta sección incluimos análisis cluster completos de algunos
bancos de datos. Utilizamos herramientas no solamente de este tema
sino también de los anteriores.
library("ALL")
data("ALL")
class(ALL)
## [1] "ExpressionSet"
## attr(,"package")
## [1] "Biobase"
bcell = grep("^B",as.character(ALL$BT))
types = c("NEG","BCR/ABL")
moltyp = which(as.character(ALL$mol.biol) %in% types)
all = ALL[,intersect(bcell,moltyp)]
tipos = ALL$mol.biol[intersect(bcell,moltyp)]
tipos = factor(tipos) ## Eliminamos categorías vacías
class(all)
## [1] "ExpressionSet"
## attr(,"package")
## [1] "Biobase"
library(cluster)
all1.d = dist(exprs(all1),method = "manhattan")
all1.km = kmeans(exprs(all1),2)
table(all1.km$cluster)
##
## 1 2
## 272 501
summary(silhouette(all1.km$cluster,all1.d))
png(paste0(dirTamiFigures,"Cluster71.png"))
plot(silhouette(all1.km$cluster,all1.d))
dev.off()
## pdf
## 2
all1.ag = hclust(all1.d,method="average")
dd = dist(t(exprs(all1)),method="euclidian")
muestras.ag = hclust(dd,method="average")
png(paste0(dirTamiFigures,"Cluster75.png"))
ggdendro::ggdendrogram(muestras.ag)
dev.off()
## pdf
## 2
tipos.ag = cutree(muestras.ag,2)
table(tipos,tipos.ag)
## tipos.ag
## tipos 1 2
## BCR/ABL 33 4
## NEG 32 10
png(paste0(dirTamiFigures,"Cluster79.png"))
heatmap(exprs(all1),hclustfun=agnes)
dev.off()
## pdf
## 2
Reflexionar qué nos da este dibujo. ¿Para qué nos puede servir un
dibujo como este? Básicamente podemos intentar ver si hay grupos
formados por filas (genes) y columnas (muestras).
Supongamos que nos planteamos un PAM y un k-medias con dos
grupos para las muestras. Vamos a clasificar con cada uno de los mé-
todos e intentar ver si hay relación con la variabel tipos que contiene
la biología molecular.
Figura 14.13: Heatmap
all1.pam = pam(t(exprs(all1)),2)
table(tipos,all1.pam$cluster)
##
## tipos 1 2
## BCR/ABL 26 11
## NEG 24 18
all1.km = kmeans(t(exprs(all1)),2)
table(tipos,all1.km$cluster)
##
## tipos 1 2
## BCR/ABL 10 27
## NEG 21 21
data(gse20986,package="tamidata")
gse = gse20986
library(genefilter)
gse0 = nsFilter(gse,var.func = mean, var.cutoff = 0.7)
gse1 = nsFilter(gse0$eset,var.func = IQR, var.cutoff = 0.7)
gse = gse1$eset
dim(exprs(gse))
## [1] 1817 12
d0 = dist(t(exprs(gse)),method = "manhattan")
Y aplicamos PAM.
library(cluster)
gse.pam = pam(d0,diss = TRUE,k=4)
La clasificación original es
tipo0 = rep(1:4,rep(3,4))
table(tipo0,gse.pam$clustering)
##
## tipo0 1 2 3 4
## 1 1 1 1 0
## 2 2 1 0 0
## 3 3 0 0 0
## 4 0 0 0 3
14.12 Ejercicios
Ejercicio 27
Utilizando los datos ALL se pide:
1. Filtrar las muestras (columnas) con biología molecular “BCR/ABL”
y “NEG”.
2. Quedarse con los genes (filas) que verifiquen las siguientes con-
diciones:
(a) La media de los niveles de expresión sobre las biologías
moleculares indicadas sea superior a 5.62.
(b) La desviación estándar de las expresiones del gen ha de ser
superior a 1.85.
3. Aplicar un análisis cluster jerárquico a los genes. En concreto:
(a) Hay que representar el dendograma.
(b) Decidir por inspección visual qué número de grupos parece
razonable. Supongamos que denotamos por k el número de
grupos.
(c) Representar la silueta y obtener su anchura media.
4. Aplicar un análisis cluster jerárquico a las muestras. En concre-
to:
Análisis de grupos de
genes
245
Capítulo 15
Grupos de genes
15.1 Introducción
Hasta ahora hemos trabajado habitualmente a nivel de gen. Ca-
da gen en cada muestra nos da un nivel de expresión. Obviamente
esto supone que por muestra tenemos una muy alta dimensión. Un
análisis de expresión diferencial supone que tenemos un contraste por
gen. Muchos miles de contrastes supone esto. Si pretendemos clasifi-
car la muestra en distintos fenotipos entonces la dimensión alta con
la que trabajamos produce un sobreajuste y modelos que no son gene-
ralizables a otros datos. En ambos problemas no es bueno tener una
dimensión tan alta. Podemos utilizar componentes principales para
resumir el perfil de expresión de la muestra (§ 13). Otra opción puede
ser trabajar no con genes individuales sino con grupos de genes. Si nos
interesa la expresión diferencial entre condiciones entonces podemos
valorar si el grupo de genes que nos interese, como grupo, se expresa
diferencialmente. Si vamos a clasificar en fenotipos, podemos resumir
la expresión de los genes en una muestra dentro de cada grupo. Re-
ducimos el número de hipótesis a contrastar (expresión diferencial) o
bien la dimensión del vector que utilizamos para clasificar (clasifica-
ción en fenotipo).
Obviamente podemos construir el grupo de genes que nos apetez-
ca y evaluarlo. No parece algo muy lógico. Es de sobra conocido en
la literatura estadística que un contraste de hipótesis es útil en la
misma medida en que está correctamente formulado. Y formular co-
rrectamente el contraste supone conocimiento sobre el problema que
abordamos. En este caso la comunidad científica ha propuesto y pro-
pone y propondrá clasificaciones que se han de utilizar para definir
estos grupos.
Tres fuentes vamos a utilizar a la hora de considerar grupos de
genes.
MSigDB En MSigDB 196 consideran hasta ocho formas distintas de 196 The Molecular Signatu-
construir estos grupos. res Database
247
248 CAPÍTULO 15. GRUPOS DE GENES
En http://www.genesetdb.auckland.ac.nz/haeremai.html te-
nemos una herramienta web que contiene a su vez a otras muchas ba-
ses de datos. Realiza análisis de sobre representación y está orientada
a humanos, ratones y ratas.
Como vemos hay muchas formas de definir estos grupos. En cual-
quier caso en su definición interviene un conocimiento previo. No uti-
lizamos los propios datos de expresión con los que posteriormente
197
No son grupos obtenidos vamos a trabajar.197
por un análisis cluster pre- En este tema tratamos de cómo construir grupos de genes utili-
vio. zando R/Bioconductor. Es un tema de carácter muy técnico previo
al que sigue en donde analizaremos la posible expresión diferencial de
198
Siempre nuestro interés estos grupos.198
principal. Vamos a definir conjuntos de genes o colecciones de conjuntos de
genes utilizando el paquete [99, GSEABase].
library(GSEABase)
data(gse20986,package="tamidata")
eset = gse20986
345:405
## [1] 345 346 347 348 349 350 351 352 353 354 355
## [12] 356 357 358 359 360 361 362 363 364 365 366
## [23] 367 368 369 370 371 372 373 374 375 376 377
## [34] 378 379 380 381 382 383 384 385 386 387 388
## [45] 389 390 391 392 393 394 395 396 397 398 399
## [56] 400 401 402 403 404 405
head(geneIds(egs))
details(egs)
## setName: Burjasot
## geneIds: 1552739_s_at, 1552740_at, ..., 1552822_at (total: 61)
## geneIdType: Annotation (hgu133plus2)
## collectionType: ExpressionSet
## setIdentifier: debian:7754:Tue Feb 5 17:11:41 2019:1
## description:
## organism: Homo sapiens
## pubMedIds:
## urls:
## contributor:
## setVersion: 0.0.1
## creationDate:
gsc
## GeneSetCollection
## names: GO:0000002, GO:0000011, ..., GO:2001070 (17312 total)
## unique identifiers: 1555591_at, 201917_s_at, ..., 1552675_at (37100 total)
## types in collection:
## geneIdType: AnnotationIdentifier (1 total)
## collectionType: GOCollection (1 total)
gsc[["GO:0000122"]]
## setName: GO:0000122
## geneIds: 1487_at, 1552338_at, ..., AFFX-HUMISGF3A/M97935_MB_at (total: 1936)
## geneIdType: Annotation (hgu133plus2)
## collectionType: GO
## ids: GO:0000122 (1 total)
## evidenceCode: EXP IDA IPI IMP IGI IEP ISS ISO ISA ISM IGC IBA IBD IKR IRD RCA TAS N
## ontology: CC MF BP
## details: use 'details(object)'
head(geneIds(gsc),n=1)
## $`GO:0000002`
## [1] "80119" "55186" "291" "4358" "1890"
## [6] "4205" "9361" "4976" "10000" "63875"
## [11] "84275" "92667"
head(sapply(geneIds(gsc), length))
geneIds(gsc.filt)
library(org.Sc.sgd.db)
frame = toTable(org.Sc.sgdGO)
goframeData = data.frame(frame$go_id, frame$Evidence, frame$systematic_name)
goFrame = GOFrame(goframeData, organism = "Saccharomyces cerevisiae")
goAllFrame = GOAllFrame(goFrame)
gscSc = GeneSetCollection(goAllFrame, setType = GOCollection())
15.4. GRUPOS PARA GSE1397 251
Y lo guardamos.
Habitualmente cuando queramos utilizar estos grupos tendremos
que hacer dos cosas:
1. Quedarnos con aquellos genes que aparecen en nuestra platafor-
ma.
2. Quedarnos posiblemente con grupos de genes con un tamaño
mínimo.
Para ello vamos a utilizar la siguiente función.
data(gse6647,package="tamidata")
data(gse1397,package="tamidata")
library(annotate)
annotation(gse1397)
## [1] "hgu133a"
library(hgu133a.db)
library(GSEABase)
gse1397.gsc = GeneSetCollection(gse1397,setType=GOCollection())
names(gse1397.gsc) = unlist(lapply(gse1397.gsc,setName))
gsc = gse1397.gsc
length(gsc)
## [1] 16445
(g1 = gsc[[1]])
## setName: GO:0000002
## geneIds: 201917_s_at, 201918_at, ..., 222216_s_at (total: 18)
## geneIdType: Annotation (hgu133a)
## collectionType: GO
## ids: GO:0000002 (1 total)
## evidenceCode: EXP IDA IPI IMP IGI IEP ISS ISO ISA ISM IGC IBA IBD IKR IRD RCA TAS N
## ontology: CC MF BP
## details: use 'details(object)'
geneIds(g1)
unlist(mget(geneIds(g1),hgu133aENTREZID))
unlist(mget(geneIds(g1),hgu133aENSEMBL))
## 201917_s_at 201918_at
## "ENSG00000114120" "ENSG00000114120"
## 201919_at 202825_at
## "ENSG00000114120" "ENSG00000151729"
## 203466_at 204858_s_at
## "ENSG00000115204" "ENSG00000025708"
## 208328_s_at 209017_s_at
## "ENSG00000068305" "ENSG00000196365"
15.5. GRUPOS GO PARA LEVADURA 253
## 212213_x_at 212214_at
## "ENSG00000198836" "ENSG00000198836"
## 212607_at1 212607_at2
## "ENSG00000117020" "ENSG00000275199"
## 212609_s_at1 212609_s_at2
## "ENSG00000117020" "ENSG00000275199"
## 214306_at 214684_at
## "ENSG00000198836" "ENSG00000068305"
## 214821_at 217497_at
## "ENSG00000151729" "ENSG00000025708"
## 219393_s_at1 219393_s_at2
## "ENSG00000117020" "ENSG00000275199"
## 222216_s_at
## "ENSG00000158042"
head(table(sapply(geneIds(gsc),length)))
##
## 1 2 3 4 5 6
## 2999 2047 1601 1263 983 711
Podemos ver que de tamaño uno tenemos 2336 grupos. Nos que-
damos con aquellos grupos que, al menos, tienen 50 genes.
library(org.Sc.sgd.db)
frame = toTable(org.Sc.sgdGO)
goframeData = data.frame(frame$go_id, frame$Evidence, frame$systematic_name)
goFrame = GOFrame(goframeData, organism = "Saccharomyces cerevisiae")
goAllFrame = GOAllFrame(goFrame)
gscSc = GeneSetCollection(goAllFrame, setType = GOCollection())
save(gscSc,file=paste0(dirTamiData,"gscSc.rda"))
gsc1[[1]]
254 CAPÍTULO 15. GRUPOS DE GENES
## setName: GO:0000001
## geneIds: YNL304W, YHR194W, ..., YNR035C (total: 29)
## geneIdType:
## collectionType: GO
## ids: GO:0000001 (1 total)
## evidenceCode: EXP IDA IPI IMP IGI IEP ISS ISO ISA ISM IGC IBA IBD IKR IRD RCA TAS N
## ontology: CC MF BP
## details: use 'details(object)'
pacman::p_load("ath1121501.db")
frame = toTable(org.At.tairGO)
goframeData = data.frame(frame$go_id, frame$Evidence, frame$gene_id)
goFrame = GOFrame(goframeData, organism = "Arabidopsis")
goAllFrame = GOAllFrame(goFrame)
gscAt = GeneSetCollection(goAllFrame, setType = GOCollection())
gscAt = geneIds(gscAt)
save(gscAt,file = paste0(dirTamiData,"gscAt.rda"))
15.8 Ejercicios
Ej. 28 — Construir los grupos basados en Gene Ontology y en KEGG
para el ratón (Mus musculus).
16.1 Introducción
Por alguna razón (que desconozco) a este procedimiento se le llama
en numerosas publicaciones de perfil biológico test hipergeométrico. 1
En lo tratado hasta este momento hemos obtenido una ordenación
de los genes. Esta lista la hemos estudiado pretendiendo que cuando
mayor sea la expresión diferencial del gen este aparezca antes en la
lista. De este modo el primer gen es el marginalmente (o si se prefiere
individualmente) tiene una mayor expresión diferencial y así sucesiva-
mente. De hecho, el p-valor no es más que una medida de esa diferen-
ciación. Una expresión muy utilizada en la literatura es que que hay
una asociación entre el gen (su expresión) y el fenotipo.201 De algu- 201
La expresión fenotipo se
na forma el p-valor que obtenemos en cada test es una cuantificación usa de un modo muy am-
de la asociación gen-fenotipo. Luego modificamos estos p-valores de plio porque podemos estar
forma que se tiene en cuenta todos los genes que simultáneamente se hablando de características
están estudiando. Obtenemos de este modo unos p-valores ajustados. fenotípicas o simplemente un
Finalmente, tanto los p-valores originales como los ajustados no de- diseño experimental con fac-
jan de ser cuantificaciones marginales de la asociación gen-fenotipo. tores temporales o diferentes
Cuando hemos fijado una tasa de error (FDR o FWER) lo que ha- temperaturas.
cemos es fijar un punto de corte. En esa lista que hemos construido
decidimos (con algún criterio de error) en qué punto de la lista cor-
tamos. Los genes que están antes del punto de corte se consideran
significativos y los que siguen no. Reducimos nuestra información a
un si (gen significativo o que tiene expresión diferencial o que hay
asociación gen-fenotipo2 o un no (no es significativo, no hay expresión
diferencial o no hay asociación gen-fenotipo).
Ya tenemos ese conjunto de genes significativos. Incluso hemos vis-
to cómo generar unos enlaces para que gen a gen examinemos alguna
base de datos online. Es claro que el investigador puede ir generando
hipótesis sobre qué indica esta lista. Pero claramente no es una labor
simple. Una posible ayuda puede ser utilizar información previamente
generada por la comunidad científica sobre grupos de genes. Grupos
que indican que tienen relación con una misma función, o que están
localizados próximos en un mismo cromosoma. En fin, grupos con
1 La razón de este nombre sí la entiendo (la distribución del estadístico de
255
256 CAPÍTULO 16. TEST DE FISHER UNILATERAL
S1 S1c = G \ S1
S0 n11 n12 n1·
S0c = G \ S0 n21 n22 n2·
n·1 n·2 N
sentido (biológico).
Un poco de notación que nunca es mala. Sea G es el conjunto de
genes considerado. ¿Quién es este conjunto? En un estudio con micro-
arrays uno diría que es el conjunto de genes que se está explorando.
Sin embargo, un chip suele estar diseñado para observar tanto genes
como se pueda y no hay una selección previa. Quizás no sea muy razo-
nable considerar el conjunto total de genes este. En otros casos no es
así. Lo fundamental es darse cuenta que lo que hacemos depende de
un modo esencial del conjunto total de genes considerado o universo.
S0 (⊂ G) el conjunto de genes que nuestro estudio ha indicado como
significativo y S1 un conjunto de genes predefinido (misma función,
misma localización). Un primer problema es definir los conjuntos S1
202
§ 15. con los que comparar.202 Una vez definidos nuestro conjunto (S0 ), el
conjunto con el que queremos comparar (S1 ) y el conjunto total de
genes considerado (G) la situación que se presenta la tenemos refleja-
da en la tabla 16.1. En esta tabla n11 indica el número de genes que
están tanto en S0 como en S1 , también tendremos n12 genes que están
en S0 pero no en S1 , n21 en S1 pero no en S0 y, finalmente, n22 que
no están ni en S0 ni en S1 . Suponemos que el total de genes (nuestro
universo de genes) G tiene un total de N genes.
En la tabla 16.1 consideramos dados los totales de la fila y la co-
lumna, en otras palabras, consideramos fijos los valores de n1· y n2·
(totales de fila) así como los valores de n·1 y n·2 (totales de columna).
Asumiendo fijos estos totales de fila y columna: ¿cuál es la probabili-
dad de observar la tabla 16.1? Utilizando argumentos combinatorios
la respuesta es la siguiente: Si denotamos N11 el número aleatorio de
genes en común entonces, bajo la hipótesis de que no hay ningún tipo
de asociación entre fila y columna, entonces la probabilidad sería
( n1· )( n2·
)
n11 n·1 −n11
P (N11 = n11 ) = (N ) .
n·1
S1 S1c
S0 30 40 70
S0c 120 156 276
150 196 346
16.2 fisher.test
Supongamos que hemos observado la tabla 16.2 y pretendemos
saber si el solapamiento entre ambos conjuntos de genes es mayor
que el esperable por el puro azar aunque no estén asociados ambos
conjuntos.
Podemos utilizar el test exacto de Fisher direccional (o unilateral
o de una cola)
conteos = matrix(c(30,120,40,156),ncol=2)
fisher.test(conteos,alternative = "greater")
##
## Fisher's Exact Test for Count Data
##
## data: conteos
## p-value = 0.589
## alternative hypothesis: true odds ratio is greater than 1
## 95 percent confidence interval:
## 0.6018802 Inf
## sample estimates:
## odds ratio
## 0.9750673
fisher.test(conteos,alternative = "less")
##
## Fisher's Exact Test for Count Data
##
## data: conteos
## p-value = 0.5179
## alternative hypothesis: true odds ratio is less than 1
## 95 percent confidence interval:
## 0.000000 1.571751
## sample estimates:
## odds ratio
## 0.9750673
S1 G \ S1
S0 30 40 70
G \ S0 120 156 + k 276 + k
150 196 + k 346 + k
## pdf
## 2
## pdf
## 2
16.4.1 GSE1397
Leemos los datos normalizados.
16.4. UTILIZANDO CATEGORY Y GOSTATS 259
0.6
1.8
0.5
0.4
1.6
Odds ratio
p−valores
0.3
1.4
0.2
1.2
0.1
1.0
0.0
0 50 100 150 0 50 100 150
k k
(a) (b)
pacman::p_load(Biobase)
data(gse1397,package = "tamidata")
eset = gse1397
y = pData(eset)[,"type"]
remove(gse1397) ## Ahorramos memoria
pacman::p_load(genefilter,multtest)
tt = rowttests(eset,y)
p0 = tt$p.value
p1 = mt.rawp2adjp(p0, "BH")
orden.original = order(p1$index)
p.BH = p1$adjp[orden.original,2]
significativos = which(p.BH < 0.05)
## [1] "hgu133a"
library(hgu133a.db)
## [1] 6
## [1] 0
seleccionados = unlist(mget(featureNames(eset[significativos,]),
hgu133aENTREZID))
pacman::p_load(GO.db,Category,GOstats)
204
En http:// Y realizamos los tests.204
geneontology.org/ te-
nemos una aplicación en params = new("GOHyperGParams", geneIds = seleccionados,
línea que nos realiza un universeGeneIds = G2.entrezid,
análisis similar. annotation = annotation(eset), ontology = "BP",
pvalueCutoff = 0.001,conditional = FALSE,
testDirection = "over")
overRepresented = hyperGTest(params)
head(summary(overRepresented))
library(Rgraphviz)
plot(goDag(overRepresented))
16.4. UTILIZANDO CATEGORY Y GOSTATS 261
library(Rgraphviz)
png(file=paste(dirTamiFigures,"GSE1397overRepresented.png",sep=""))
plot(goDag(overRepresented))
dev.off()
16.4.2 GSE20986
Leemos los datos normalizados y lo renombramos.
Biobase::annotation(gse)
## [1] "hgu133plus2"
library("hgu133plus2.db")
library(genefilter)
gse.filt = genefilter::nsFilter(gse, var.func = IQR, var.cutoff = 0.6,
require.GOBP = TRUE)$eset
dim(gse.filt)
## Features Samples
## 6164 12
## [1] 0
## [1] 6
## [1] 0
library(multtest)
gse.aov = rowFtests(gse.filt2, pData(gse20986)[,"tissue"])
p.originales = gse.aov[, 2]
p.BH = mt.rawp2adjp(p.originales, "BH")
pvalores = p.BH$adjp[p.BH$index, 2]
sig.1234 = which(pvalores < 0.001)
selected = unlist(mget(featureNames(gse.filt2[sig.1234,]), hgu133plus2ENTREZID))
library(GO.db);library(Category);library(GOstats)
fl = tempfile()
htmlReport(overRepresented, file = fl)
browseURL(fl)
16.4.3 ALL
Esta sección se reproduce el análisis propuesto en http://www.
bioconductor.org/help/course-materials/2009/SSCMay09/gsea/
HyperG_Lecture.pdf. Utilizamos los datos [86, ALL]. En § 5.4 se in-
dica cómo conseguir los datos bcrneg en donde hemos seleccionado
algunas muestras. Los datos los tenemos en bcrneg. Veamos número
de genes y muestras.
dim(bcrneg)
## Features Samples
## 12625 79
dim(bcrneg.filt)
## Features Samples
## 4076 79
InGO
Selected FALSE TRUE
FALSE 3101 162
TRUE 658 30
names(rttPrb) = featureNames(bcrneg.filt)
ids = featureNames(bcrneg.filt)
map = hgu95av2ENTREZID
library(GO.db)
GOTERM[["GO:0006468"]]
## GOID: GO:0006468
## Term: protein phosphorylation
## Ontology: BP
## Definition: The process of introducing a
## phosphate group on to a protein.
## Synonym: protein amino acid phosphorylation
library(Category)
library(GOstats)
Veamos el resumen.
head(summary(overRepresented), n = 3)
fl = tempfile()
htmlReport(overRepresented, file = fl)
browseURL(fl)
16.5 Ejercicios
Ejercicio 31
Utilizamos los datos tamidata::gse20986. En el problema 21 hemos
determinado los genes significativos con un FDR de 0.05 para las com-
paraciones entre las muestras obtenidas en el iris, retina y coroides con
las muestras huvec. Tenemos pues tres grupos de genes significativos
que podemos denotar Siris , Sretina y Scoroides .
Análisis de conjuntos de
genes
17.1 Introduction
1
267
268 CAPÍTULO 17. ANÁLISIS DE CONJUNTOS DE GENES
Notemos que Xij es una variable aleatoria mientras que xij es un valor
observado. Las columnas de la matriz de expresión X son indepen-
207
Corriendo un tupido velo dientes. Son vectores aleatorios independientes207 Por tanto podemos
por toda la parte de prepro- considerar que las distintas muestras son realizaciones de vectores
cesado de la información que independientes aunque no con la misma distribución ya que son ob-
hemos visto en § 4 para datos servados bajo distintas condiciones experimentales. Si nos fijamos en
de microarrays. Es claro que las filas de la matriz de expresión, esto es, en los perfiles de expresión
el preprocesado de la infor- entonces tenemos realizaciones de vectores aleatorios dependientes y
mación introduce dependen- que además no tienen la misma distribución. Los genes no son in-
cias entre valores observados dependientes en su comportamiento hay corregulaciones entre ellos.
para distintas muestras pero Además tampoco tienen porqué comportarse de un modo (aleatorio)
las ignoramos. común.
17.4 Ejemplos
En esta sección comentamos los ejemplos que utilizamos.
N = 1000; n = 50
set.seed(280562) ## Para obtener los mismos valores generados
et1 = matrix(rnorm(N*n),nrow = N,ncol = n)
et1[1:10,26:50] = et1[1:10,26:50] + 2.5
et1.tt = genefilter::rowttests(et1,y.et)$statistic
pacman::p_load("ggplot2")
df = data.frame(et1.tt)
png(paste0(dirTamiFigures,"GeneSetAnalysis5b.png"))
ggplot(df,aes(x=et1.tt))+geom_density()
dev.off()
## pdf
## 2
N = 1000; n = 50
set.seed(280562)
indices.temp = (0:49)*20 + 1
indices = NULL
for(i in indices.temp) indices = c(indices,i:(i+9))
et2 = matrix(rnorm(N*n),nrow = N,ncol = n)
et2[indices,26:50] = et1[1:10,26:50] + 2.5
et2.tt = genefilter::rowttests(et2,y.et)$statistic
pacman::p_load("ggplot2")
df = data.frame(et2.tt)
png(paste0(dirTamiFigures,"GeneSetAnalysis11c.png"))
ggplot(df,aes(x=et2.tt))+geom_density()
dev.off()
## pdf
## 2
u = et1[1,]
t0 = t.test(u ~ y.et)$statistic
t0 = abs(t0)
B = 100
tb = rep(0,B)
for(i in 1:B) tb[i] = t.test(u ~ sample(y.et))$statistic
tb = abs(tb)
## [1] 0
pacman::p_load(limma)
geneSetTest(1:20,et1.tt,alternative ="up")
## [1] 0.9984722
geneSetTest(1:20,et1.tt,alternative ="down")
## [1] 0.00153168
pvalores = NULL
for(i in 0:49){
indices = (i * 20 + 1): (i * 20 + 10)
p.temp = geneSetTest(indices,et1.tt,alternative ="down")
pvalores = c(pvalores,p.temp)
}
17.9 Limma::wilcoxGST
Siguiendo con el paquete [130, limma] una opción simple (no ne-
cesariamente muy potente) y que no utiliza la distribución de alea-
torización consiste en tomar los valores del estadístico en el grupo
17.10. LIMMA::CAMERA 275
wilcoxGST(1:20,et1.tt,alternative ="down")
## [1] 0.00153168
wilcoxGST(1:20,et1.tt,alternative ="up")
## [1] 0.9984722
wilcoxGST(1:20,et1.tt,alternative ="mixed")
## [1] 2.837697e-08
wilcoxGST(21:30,et1.tt,alternative ="down")
## [1] 0.09546351
wilcoxGST(21:30,et1.tt,alternative ="up")
## [1] 0.904723
wilcoxGST(21:30,et1.tt,alternative ="mixed")
## [1] 0.8181643
17.10 Limma::CAMERA
El método fue propuesto en [155].214 Es un procedimiento para 214 El nombre es un acró-
contrastar la hipótesis competitiva. Es un procedimiento que tiene en nimo Correlation Adjusted
cuenta la correlación entre las expresiones de los distintos genes en MEan RAnk.
cada muestra. La mayor parte de los procemientos propuestos para
el contraste de la hipótesis competitiva suelen asumir (falsamente)
la independencia de la expresión observada para distintos genes y su
validez depende una hipótesis que sabemos no es cierta. Se ha visto
que no tener en cuenta esta dependencia entre genes nos lleva a un
incremento de la tasa de error FDR.
Se asume que la expresión está cuantificada en escala logarítmica
(base 2 como es habitual en este contexto).
∑
p
E[Xij ] = µij = αik yjk (17.6)
k=1
276 CAPÍTULO 17. ANÁLISIS DE CONJUNTOS DE GENES
17.11 GSA
219 219
En el paquete [43, GSA] Se utiliza la distribución de permutación a la que aplican una
se implementa el método reestandarización. La medida de enriquecimiento que proponen por
propuesto en [44]. defecto 3 es la siguiente: partimos de los valores ti que miden aso-
ciación gen-fenotipo. Definimos t+ = max{t, 0} y t− = − min{t, 0}.
∑ t+
Consideramos un conjunto de genes S. Definimos t̄S+ = i∈S nS y
i
∑ −
t̄−
ti
S = i∈S nS . Finalmente la medida de enriquecimiento (que llama-
remos el estadístico maxmean) es
−
S , t̄S }.
t(S) = max{t̄+ (17.7)
Estamos tomando la media de las partes positivas t+
i , la media de las
partes negativas t−
i y nos quedamos con el máximo de ambos valores.
Ejemplo 17.6 [44, página 119] La medida de enriquecimento que
acabamos de definir es robusta frente al caso en que tengamos una
medida extrema. El ejemplo que proponen los autores es el siguiente:
supongamos que tenemos 100 genes, 99 de los valores ti ’s son -0.5
−
y el valor restante es 10. Tenemos que t̄+ S = 10/100 = 0.1 y t̄S =
−99(−0.5)/100 = 0.495. Vemos que los valores negativos dominan
pues son la mayor parte de los datos. Si se tomara la media de las
partes positivas t+ y la media de las partes negativas t− tendríamos los
valores 10 y -0.5 (es decir, solamente consideramos cuando el valor no
es nulo) y la medida de enriquecimiento vendría dominada por valores
extremos.
Como medidas de asociación gen-prototipo ti utilizan las mismas del
paquete [138, samr] que aparecen en la sección § 9.1.1. Cuando anali-
zan los conjuntos de genes hablan de grupos de genes positivos y grupos
de genes negativos. Un grupo de genes se dice negativo si corresponden
con genes que en la clase 2 tiene expresiones menores cuando tenemos
dos grupos (1 y 2). Si tenemos una covariable y numérica entonces
los negativos corresponden al caso en que expresiones menores se aso-
cian a valores mayores de y. Los grupos positivos se definen de modo
contrario a los positivos. Cargamos el paquete.
3 Aunque lleva el promedio de los ti ’s y el promedio de |ti | como otras opciones.
17.11. GSA 277
pacman::p_load(GSA)
head(et1.gsa$GSA.scores)
summary(et1.gsa$GSA.scores[-1])
head(et1.gsa$pvalues.lo)
head(et1.gsa$pvalues.hi)
summary(et1.gsa$pvalues.hi[-1])
head(et1.gsa$gene.scores)
parte inferior con el resto de los genes. El análisis de grupo que hemos
−1
●
●
●
●
Grupo 1 Resto
En la figura 17.4 tenemos los grupos de genes que se considerarían
significativos (diferenciando grupos up y down) y el valor de FDR para
Figura 17.3: Valores ti para el que los declaremos significativos en los datos et1 (ejemplo 17.1).
primer grupo (izquierda) y los
demás. El primer grupo tiene GSA.plot(et1.gsa)
diez genes claramente diferencia-
dos mientras que los demás no lo
están. De ahí la gran variabilidad Vemos cómo solamente admitimos un grupo con un valor bajo de
que muestra el grupo. FDR.
o Negative
o Positive diferenciado del grupo respecto de los otros grupos. Los datos son
0.050
et2 mientras que los grupos los tenemos en gsc.et con nombres en
gsnames.et. Finalmente genenames.tt nos da los nombres de los
0.005
genes.
0.001
●● ●
GSA.plot(et2.gsa)
False discovery rate
0.75
●
● ●
● ● ●
●
data(gse1397,package="tamidata")
0.05 0.10 0.20 0.50
data(gse1397.gsc,package="tamidata")
p−value
gsc = gse1397.gsc
Figura 17.5: Grupos significativos gruposGrandes = which(sapply(geneIds(gsc),length) > 50)
con datos et2 en función de FDR. gsc = gsc[gruposGrandes]
gse = gse1397
tipo.num = as.numeric(pData(gse)[,"type"])
0.500
●
0.050
GSA.plot(gse1397.gsa)
0.005
●
Fijamos una tasa de error de 0.05. Veamos qué grupos son los
0.001
que o bien con una asociación negativa o bien con asociación positiva 0.001 0.005 0.020 0.100 0.500
son los que presentan una mayor diferenciación entre los dos grupos p−value
head(names(gsc[ind.lo]))
y análogamente
head(names(gsc[ind.hi]))
Y ahora viene el trabajo del especialista para ver hasta qué punto
lo que sale tiene sentido o no.
Método
Empezamos ordenando el universo de genes de acuerdo al grado
de asociación gen-fenotipo utilizando algunos de los estadísticos pro-
puestos en § 17.5. Tendremos la lista de genes ordenada, L.
Entradas 1. La matriz de expresión X con N filas y n columnas.
2. Procedimiento de ordenación con objeto de producir la lista
ordenada de genes, L.
3. Un valor p
4. Un conjunto de genes S.
Cálculo del enriquecimiento 1. Calculamos medida de asocia-
ción gen-fenotipo, ti .
2. Ordenamos el universo de genes de acuerdo a las medidas
de asociación del paso 1. Denotamos los índices ordenados
con r1 . . . , rN , es decir,
tr1 ≥ . . . ≥ trN .
Calculamos también
∑ 1
mS (i) = , (17.9)
N − nS
j≤i;rj ∈S
/
y ∑ eSk ,πi
ē− = .
|{k, i : eSk ,πi < 0}|
k,i:eSk ,πi <0
∫ xij −xik
1∑
n
hi 1 t2
F̂hi (xij ) = √ e− 2 dt. (17.17)
n −∞ 2π
k=1
17.17. OTROS PAQUETES Y BIBLIOGRAFÍA COMPLEMENTARIA285
si
El ancho de banda hi lo fijan en hi = 4 siendo si la desviación
estándar de xi .
Para datos de conteo (RNA-seq) utilizan un kernel de Poisson.
En concreto el estimador kernel de la función de distribución
propuesto es
1 ∑ ∑ −(xik +r xik + r
n xij
F̂r (xij ) = e , (17.18)
n y=0
y!
k=1
con
νjk (s∗) = max{νjk (s) : s = 1, . . . , N }. (17.21)
Una segunda opción para resumir es considerar
dif f
Ejk = max {0, νjk (s)} − min {0, νjk (s)}. (17.22)
s=1,...,N s=1,...,N
Enriquecimiento de
grafos
18.1 Grafos
Un grafo no es más que una colección de vértices y aristas. Siendo
un poco más formales el grafo G sería el par G = (V, E) donde V es el
conjunto de vértices mientras que E es el conjunto de aristas. Podemos
denotar G = {1, . . . , N }. Una arista será un par (i, j). Podemos tener
grafos dirigidos, no dirigidos o mixtos.
Los vértices del grafo corresponden con genes (proteínas, grupos
de genes).
Una arista dirigida indica que el gen en el vértice origen regula al
gen en el vértice destino de la arista.
287
288 CAPÍTULO 18. ENRIQUECIMIENTO DE GRAFOS
18.2 NEAT
En esta sección consideramos el procedimiento propuesto en [125]
e implementado en [126, neat]. Consideramos un grafo cuyos vértices
corresponden con genes.
Tenemos un grafo dado describiendo las interacciones entre genes
y pretendemos si existe algún tipo de asociación (sobre o infra aso-
ciación) entre un par de grupos de genes, A y B. El grupo A podría
corresponder a un grupo diferencialmente expresado (obtenido por
ejemplo mediante un análisis de expresión diferencial marginal). El
conjunto B puede corresponder a un grupo previamente definido en
Gene Ontology o en KEGG.
Supongamos en un primer momento un grafo dirigido. Denotamos:
18.3 DEGraph
El procedimiento fue propuesto en [78] y está implementado en el
paquete [77, DEGraph].
Método
Se trata de proponer tests multivariantes para estudiar expresión
diferencial (básicamente, cambios en el vector de medias) y que sean
coherentes con una estructura de grafo dada.
Consideremos un grafo con p genes. Este grafo es G = (V, E) donde
V es el conjunto de vértices mientras que E es el conjunto de aristas.
Consideramos el vector δ ∈ Rp que nos indicará la diferencia en la
expresión media entre dos condiciones.
Sea EG una función de energía definida sobre el grafo. ¿Cómo
definirla? Veamos distintas posibilidades. Por ejemplo, consideremos
la laplaciana del grafo L Si G es un grafo no dirigido con matriz de
adjacencia A228 y matriz de grados de incidencia D = diag(A1p )229 . 228
A = [aij ]i,j=1,...,p donde
El elemento i-ésimo de la diagonal de D, Dii = di es el grado de aij = 1 si (i, j) ∈ E y cero en
incidencia del vértice i. Se define la matriz laplaciana de G como otro caso.
L = D−A y su versión normalizada como Lnorm = I −D−1/2 AD−1/2 . 229
diag(x denota la matriz
Supongamos que consideramos la función de energía definida sobre diagonal con el vector x en
un vector δ ∈ Rd como la diagonal y 1p es el vector
p × 1 con el valor 1 en cada
EG (δ) = δ ′ QG δ, (18.1) posición.
donde QG es L entonces
∑
EG (δ) = (δi − δj )2 (18.2)
i,j∈V
∑ ( δi δ
)2
EG (δ) = √ − √j (18.3)
i,j∈V
di dj
EG (δ) = δ ′ MG δ, (18.7)
−1 ′ ′ ˜ −1 ′
siendo MG = (I˜ − D− A ) (I − D− A ), D− = diag(d− −
1 , . . . , dp ) y
− −
231
El elemento I˜ es no nulo I˜ = diag(I(d1 ̸= 0), . . . , I(dp ̸= 0)) 231
Una vez tenemos esta forma
si d−
i ̸
= 0 y nulo en otro caso. cuadrática podemos hacer su descomposición en valores singulares,
MG = U ′ ΛU . En lo que sigue si x ∈ Rp entonces se denota x̃ = U ′ x.
El procedimiento propuesto consiste en lo siguiente: en lugar de
trabajar con los datos originales x se trabaja con las primeras k co-
lumnas de la matriz U correspondientes a los k vectores propios cuyos
valores propios son los k menores. Y se aplica sobre estos datos redu-
232
https://en.wikipedia. cidos un test de la T 2 de Hotelling.232 Varios comentarios son impor-
org/wiki/Hotelling's_ tantes. Obviamente no podemos aplicar el test de la T 2 de Hotelling
T-squared_distribution. por un problema de dimensión. Los autores muestran además la ga-
nancia de potencia en el test de comparación aplicando esta reducción
de dimensión. ¿Cómo queda el procedimiento? Denotamos:
1. x̄i con i = 1, 2 los vectores de medias en ambas condiciones.
233
Pooled estimator. 2. S la matriz de covarianzas estimada conjuntamente233
Si aplicáramos el test de T 2 de Hotelling entonces el estadístico del
contraste sería
n1 n2
T2 = (x̄1 − x̄2 )′ S −1 (x̄1 − x̄2 ). (18.8)
n1 + n2
Si en lugar de trabajar en la base original transformamos a una base
ortonormal formada por las columnas de U entonces el estadístico no
cambiaría. Si denotamos el estadístico en la nueva base T̃ 2 se tiene
que
n1 n2
T 2 = T̃ 2 = (x̄1 − x̄2 )′ U (U ′ SU )−1 U ′ (x̄1 − x̄2 ). (18.9)
n1 + n2
Realmente no se trabaja con la nueva base completa sino con k com-
ponentes (k ≤ p). Denotamos por U[k] la matriz formada por las
primeras k componentes de U (correspondientes a los k menores valo-
res propios) y por I[k] una matriz con todo ceros salvo los k primeros
elementos de la diagonal principal iguales a uno. Considerando la pro-
yección sobre el espacio generado por las primeras k componentes el
estadístico de Hotelling en el nuevo espacio sería
n1 n2
T̃k2 = (x̄1 − x̄2 )′ U[k] (U[k]
′
SU[k] )−1 U[k]′
(x̄1 − x̄2 ) =
n1 + n2
n1 n2
(x̄1 − x̄2 )′ U I[k] U ′ (U I[k] U ′ SU I[k] U ′ )+ U I[k] U ′ (x̄1 − x̄2 ).
n1 + n2
(18.10)
Ejemplo
library(DEGraph)
292 CAPÍTULO 18. ENRIQUECIMIENTO DE GRAFOS
Parte VI
Agregación
293
Capítulo 19
Listas de características
ordenadas
234 234
Este capítulo está basa-
En temas anteriores hemos visto cómo cuando realizamos un aná- do fundamentalmente en [20]
lisis de cada característica marginalmente obtenemos un estadístico y su implementación en el
y un p-valor asociado. Por ejemplo, en la situación más simple de paquete [128, GeneSelector].
comparación de dos grupos de muestras (dos condiciones) podemos De hecho, no es más que un
utilizar un t-test (bilateral). De hecho ordenamos las características resumen. Una buena referen-
según el módulo del estadístico es mayor o bien si el p-valor es más cia es [33].
pequeño. Ambos criterios producen la misma ordenación.235 235
Si es con el estadístico or-
En lo anterior estas listas las hemos usado sólamente a fin de de- denamos de mayor a menor
terminar en qué posición cortar de modo que por encima del punto y si es con el p-valor la or-
de corte declaramos que un test es significativo y por debajo que no denación se hace de menor a
lo es. ¿Este es el único uso que podemos realizar de esta ordenación? mayor.
No, claro. Supongamos que obtenemos 1000 características significa-
tivas con un FDR de 0.05. ¿De qué nos sirve? ¿El investigador va a
seguir estudiando cada uno de estos genes? No es probable que tenga
dinero para ello.236 Lo más probable es que elija seguir estudiando 236
Bueno, a lo mejor en
aquellos genes que aparecen en la parte superior de la lista que hemos Estados Unidos o Alemania.
construido. Por tanto, la posición en la lista tiene gran importancia. Eso dicen.
¿Cómo de estable es la ordenación que hemos obtenido? Cuando
se habla de estable hay que definir frente a qué se pretende estabili-
dad. Una primera fuente de variabilidad a la hora de obtener la lista
es utilizar distintos estadísticos (y por lo tanto distintos p-valores)
cuando contrastamos la expresión diferencial marginal. Por tanto, es-
tabilidad frente al procedimiento estadístico utilizado. Dentro de este
apartado se puede incluir el hecho que los datos hay que preprocesar-
los (correcciones de fondo, normalización y resumen en microarrays
por ejemplo) y no hay, por supuesto, un único método.
Una segunda fuente de variabilidad son modificaciones en los datos
que manejamos, pequeñas modificaciones de los mismos no debieran
afectar (demasiado) a la lista obtenida.
En consecuencia, la lista ordenada es variable y hemos de cuantifi-
car la estabilidad de la ordenación. Esto se trata en § 19.1. Un segundo
aspecto es cómo agregar distintas listas con objeto de obtener una lista
agregada más estable, más fiable. Lo vemos en § 19.2.
295
296CAPÍTULO 19. LISTAS DE CARACTERÍSTICAS ORDENADAS
rj = i ⇐⇒ π(i) = j.
library(GeneSelector)
library(tamidata)
data(gse1397)
x = exprs(gse1397)
y = pData(gse1397)[,"type"]
fc = RankingFC(x,y)
tstat = RankingTstat(x,y)
limma = RankingLimma(x,y,proportion=0.01)
foxdimmic = RankingFoxDimmic(x,y,m=100)
238
Shrinkage t-statistic. El t-estadístico de contracción238 con
shrinkt = RankingShrinkageT(x,y)
class(tstat)
## [1] "GeneRanking"
## attr(,"package")
## [1] "GeneSelector"
getSlots("GeneRanking")
## x y statistic ranking
## "matrix" "factor" "numeric" "numeric"
## pval type method
## "vector" "character" "character"
tstat@y
## [1] 1 1 1 1 1 1 1 2 2 2 2 2 2 2
## Levels: 1 2
head(tstat@ranking)
head(tstat@statistic)
head(tstat@pval)
tstat@type
## [1] "unpaired"
tstat@method
## [1] "ordinaryT"
toplist(tstat,top=10)
fc.top = toplist(fc,top=10,show=FALSE)
tstat.top = toplist(tstat,top=10,show=FALSE)
limma.top = toplist(limma,top=10,show=FALSE)
foxdimmic.top = toplist(foxdimmic,top=10,show=FALSE)
shrinkt.top = toplist(shrinkt,top=10,show=FALSE)
global.top = cbind(fc.top[,"index"],tstat.top[,"index"],limma.top[,"index"],
foxdimmic.top[,"index"],shrinkt.top[,"index"])
colnames(global.top) = c("fc","tstat","limma","foxdimmic","shrinkt")
Y obtenemos.
global.top
lista = list(fc,tstat,limma,foxdimmic,shrinkt)
genesel = GeneSelector(lista,maxrank=10)
show(genesel)
listareducida = list(tstat,limma,foxdimmic,shrinkt)
genesel = GeneSelector(listareducida,maxrank=10)
show(genesel)
which(slot(genesel,"selected") == 1)
## [1] 6303
genesel = GeneSelector(listareducida,maxrank=50)
show(genesel)
which(slot(genesel,"selected") == 1)
set.seed(1979)
Aplicamos jackknife con dejando fuera cada vez una de las mues-
244
En definitiva, un leaving- tras originales. 244 Observemos que se impone una restricción a esto
one-out. y es que cada clase ha de tener un tamaño de, al menos, 6 muestras.
leave1out.tstat = RepeatRanking(tstat,leave1out,scheme="subsampling")
png(paste0(dirTamiFigures,"ListasOrdenadas25.png"))
plot(leave1out.tstat)
dev.off()
change1.tstat = RepeatRanking(tstat,leave1out,scheme="labelexchange")
También generamos muestras bootstrap imponiendo la misma res- 245 Lo que significa que asig-
tricción sobre el tamaño de cada clase. namos esa muestra al otro
grupo.
boot = GenerateBootMatrix(y = as.numeric(y), replicates = 50,
maxties = 3,minclassize=6)
boot.tstat = RepeatRanking(tstat,boot)
toplist(boot.tstat,show = FALSE)
Vemos que nos muestra la tabla original con los diez primeros
genes, el t-estadístico y el p-valor. La siguiente tabla de frecuencias
muestras los genes que han aparecido al menos una vez entre los 10
primeros y la frecuencia de veces que aparece en cada una de las 10
primeras posiciones.
En la figura 19.1 mostramos las ordenaciones originales en abscisas
frente a las observadas cuando modificamos los datos según los dis-
tintos procedimientos. Es más que evidente la tremenda variabilidad
que obtenemos en las ordenaciones.
par(mfrow=c(2,2))
plot(leave1out.tstat, col="blue",
pch=".", cex=2.5, main = "jackknife")
plot(change1.tstat, col="blue",
pch=".", cex=2.5, main = "intercambio etiqueta")
plot(boot.tstat, col="blue",
pch=".", cex=2.5, main = "bootstrap")
plot(noise.tstat, frac=1/10,
col="blue", pch=".", cex=2.5, main = "ruido")
302CAPÍTULO 19. LISTAS DE CARACTERÍSTICAS ORDENADAS
400
200
200
0
0 50 150 0 50 150
bootstrap ruido
Ranks in perturbed datasets
2000
200
0
Figura 19.1: Orden original frente a los obtenidos modificando los datos.
19.2. AGREGACIÓN DE LISTAS 303
merged = MergeMethods(lista)
HeatmapRankings(merged) HeatmapRankings(merged)
Hemos de agregar las ordenaciones. La opción más básica sería Figura 19.2: Heatmap para las or-
promediar, por gen, los órdenes obtenidos. denaciones obtenidas con distin-
tos estadísticos.
Probabilidad y
Estadística
305
Capítulo 20
Estadística descriptiva
20.1 Datos
Vamos a trabajar con datos de expresión obtenidos mediante mi-
croarrays para un gen determinado. Tomamos los datos en la fila 3109
de tamidata:gse44456.
library(Biobase)
data(gse44456,package="tamidata")
y = exprs(gse44456)[3109,]
Es el gen
featureNames(gse44456)[3109]
## [1] "7895629"
head(y)
## GSM1085665_HE32H001.CEL
## 8.339249
## GSM1085666_HE32H003.CEL
## 7.907181
## GSM1085667_HE32H004.CEL
## 7.816187
## GSM1085668_HE32H005.CEL
## 8.232150
## GSM1085669_HE32H006_2_.CEL
## 7.869529
## GSM1085670_HE32H007_2_.CEL
## 8.023928
(z = pData(gse44456)[,"case"])
307
308 CAPÍTULO 20. ESTADÍSTICA DESCRIPTIVA
df = data.frame(x =z,y=y)
20.2 Introducción
Tenemos unos datos observados en distintas muestras. De un mo-
do genérico denotaremos por x1 el primer valor observado, por x2 el
segundo valor observado y así sucesivamente. En el lenguaje estadís-
tico a esto se le llama una muestra. Por ello, diremos que tenemos
una muestra x1 , . . . , xn de n datos. Se entiende que estos datos se han
tomado en unas condiciones similares. ¿Cómo son estos datos? Pre-
tendemos describirlos de un modo sencillo. Esta descripción será de
dos tipos: una descripción numérica, describimos muchos números con
unos pocos números que tengan un sentido claro; y una descripción
gráfica. Describimos los números con gráficos que destaquen sus pro-
piedades básicas. Al conjunto de técnicas que nos dan descripciones
numéricas y gráficas de un conjunto de datos reciben el nombre de
Estadística descriptiva y, con frecuencia, simplemente descripti-
va. Se habla de la descriptiva de los datos. Veremos que son ideas
sencillas pero de un uso constante. Cuando se describen los datos las
preguntas básicas que hemos de tener en la cabeza pueden ser:
1. ¿De qué orden son?
2. ¿Cómo de dispersos están?
3. ¿Hay datos anormales que estén muy alejados de los demás?
En la primera pregunta intentamos localizar los valores: ¿estamos al-
rededor de 2?, ¿o bien alrededor de 20?, ¿o alrededor de 200000? Pre-
tendemos localizar la muestra, dar un valor representativo de todos
ellos. En la segunda pregunta nos preguntamos si los datos se agru-
pan si están próximos entre sí. Por último, nos planteamos si tenemos
datos que son anormales. Obviamente lo que es anormal depende de
cómo son los otros.
mean(y)
## [1] 7.890915
length(y)
## [1] 39
sum(y)/length(y)
## [1] 7.890915
yy = c(y,3400)
mean(y)
## [1] 7.890915
mean(yy)
## [1] 92.69364
310 CAPÍTULO 20. ESTADÍSTICA DESCRIPTIVA
mean(y,trim=.1)
## [1] 7.89261
mean(y,trim=.1)
## [1] 7.89261
mean(yy,trim=.1)
## [1] 7.901745
20.3.3 Percentiles
Otro manera de localizar los datos es utilizar los percentiles mues-
trales. Supongamos que tomamos un valor p entre 0 y 1. El percentil
de orden p es un valor que tiene por debajo el 100 × p por ciento de
los datos y por encima el 100 × (1 − p) por ciento. Denotaremos el
percentil de orden p como qp . Ordenamos nuestros datos de menor a
mayor con la función sort.
sort(y)
Fn = ecdf(y)
Fn(1)
## [1] 0
median(y)
## [1] 7.880398
quantile(y,probs = 0.27)
## 27%
## 7.778698
O bien p = 0.76
quantile(y,probs = 0.76)
## 76%
## 8.005315
quantile(y,probs = c(0.25,0.75))
## 25% 75%
## 7.763305 8.001348
var(y)
## [1] 0.05017174
2 Se pueden ver hasta nueve procedimientos distintos.
312 CAPÍTULO 20. ESTADÍSTICA DESCRIPTIVA
sd(y)
## [1] 0.2239905
20.3.5 Rango
El mínimo y el máximo lo podemos obtener con
range(y)
o bien con
min(y)
## [1] 7.320905
max(y)
## [1] 8.364369
max(y)-min(y)
## [1] 1.043464
o bien con
diff(range(y))
## [1] 1.043464
IQR(y)
## [1] 0.2380429
summary(y)
20.4 MAD
Es una forma de cuantificar variabilidad más robusta que la desvia-
ción estándar muestral. Tenemos unos datos x1 , . . . , xn . Supongamos
que m es una mediana de estos datos. Consideremos los nuevos datos
|xi −m| con i = 1, . . . , n, es decir, consideramos el valor absoluto de la
diferencia entre cada xi y la mediana. El valor de MAD es la mediana
de las valores |xi − m| con i = 1, . . . , n, esto es, la mediana de las
desviaciones absolutas respecto de la mediana de las observaciones.
En resumen,
M AD({x1 , . . . , xn }) =
mediana({|xi − mediana({x1 , . . . , xn })| : i = 1, . . . , n}) (20.4)
1 |X − µ| M AD M AD
= P (|X−µ| ≤ M AD) = P ( ≤ ) = P (|Z| ≤ )
2 σ σ σ
(20.5)
20.5 Ejercicios
Ej. 32 — Consideremos los siguientes datos.
43.86 33.14 37.04 29.29 21.49 34.98 18.09 18.84 36.20 27.82 22.86 32.11
22.45 38.22 44.55 39.03 33.25 18.27 34.44 24.88 24.58 42.12 30.04 19.58
34.00 32.98 28.35 25.75 22.78 15.88 38.97 13.47 21.42 34.19 16.49 15.17
31.42 17.00 37.06 30.35 19.65 34.62 16.48 19.42 42.89 23.89 29.26 45.64
32.29 22.96 29.60 39.98 21.86 18.25 35.96 30.57 40.79 17.21 27.07 28.56
314 CAPÍTULO 20. ESTADÍSTICA DESCRIPTIVA
15.59 23.51 18.78 37.72 14.40 28.40 43.17 22.65 27.85 41.56 42.44 16.57
23.55 29.66 20.72 28.28 42.10 13.76 27.27 19.69 20.18 23.80 14.37 22.02
29.06 34.52 21.91 19.98 16.24 44.56 18.54 35.96 30.12 32.82 45.76 28.75
32.01 19.39 23.76 41.72 32.90 31.47 15.04 12.74 44.11 38.65 27.18 35.52
15.70 38.95 30.59 15.43 45.60 14.98 23.11 22.11 23.03 19.91 34.95 16.05
Se pide:
1.Leer los datos utilizando el método que se prefiera.
2.Calcular la media, mediana, media recortada con una proporción
del 0.05, los percentiles de orden 0.1 y 0.9.
3.Supongamos que se han seguido recogiendo datos. En concreto
una segunda muestra con los siguientes valores.
123.34 78.23 89.6 1.2
Incorporar estas nuevas observaciones a los datos originales y
calcular las descriptivas numéricas anteriores sobre los nuevos
datos. Indicar cuáles de ellas varían y cuáles no justificando la
respuesta.
20.6.2 Frecuencias
La segunda variable que hemos introducido en el banco de datos
es la zona en que tomamos la medida. Es pues una variable categórica
que nos indica la pertenencia del dato a una categoría, en este caso, la
zona en que se observa el dato. La descripción básica más simple son
los conteos o frecuencias absolutas. Contamos el número de veces que
se repiten cada una de las categorías. Tendremos el número de datos
que se ha observado en cada zona. Los obtenemos de un modo simple
con la función table.
table(z)
## z
## control alcoholic
## 19 20
prop.table(table(z))
## z
## control alcoholic
## 0.4871795 0.5128205
sum(table(z))
## [1] 39
table(z)/sum(table(z))
## z
## control alcoholic
## 0.4871795 0.5128205
library(ggplot2)
df = data.frame(z)
png(paste0(dirTamiFigures,"EstDesc27.png"))
ggplot(df,aes(x = z)) + geom_bar() + xlab("strain")
dev.off()
20.6.3 Histograma
Para una variable cuantitativa una buena opción para observar la
distribución de los datos es un histograma. La idea de un histograma es Figura 20.1: Diagrama de barras
(demasiado) simple. Si x1 , . . . , xn son los datos de los cuales queremos con las frecuencias absolutas.
construir el histograma consideramos el intervalo que va del mínimo
al máximo, es decir, el intervalo
donde
b−a
δ=
k
Dependiendo del software que utilicemos los valores de a y b suelen
elegirse como un poco menos que el mínimo y un poco más que el
mínimo. El número de clases se elige de un modo automático pero
316 CAPÍTULO 20. ESTADÍSTICA DESCRIPTIVA
df0 = data.frame(y)
png(paste0(dirTamiFigures,"EstDesc29.png"))
ggplot(df0,aes(x=y))+geom_histogram()
dev.off()
## pdf
## 2
df0 = data.frame(y,z)
df1= reshape2::melt(df0)
png(paste0(dirTamiFigures,"EstDesc31.png"))
ggplot(df1,aes(x=z,y=value)) + geom_boxplot()
dev.off()
## pdf
## 2
y
K(−u) = K(u),
es decir, es simétrica respecto del origen. Una función K que se suele
utilizar es la gaussiana dada por
1
K(u) = √ e− 2 u .
1 2
2π
Otros ejemplos de funciones kernel que podemos usar las podemos ver
en http://en.wikipedia.org/wiki/Kernel_%28statistics%29.
En la figura 20.4 aparece un estimador kernel de la densidad uti-
lizando una función kernel gaussiana.
df = data.frame(y)
png(paste0(dirTamiFigures,"EstDesc32b.png"))
ggplot(df,aes(x=y)) + geom_density()
dev.off()
## pdf
## 2
## named numeric(0)
## named numeric(0)
Puede ser extremo por abajo si es menor que q25 − 1.5 × IQR o por
arriba si es mayor que q75 + 1.5 × IQR. Determinemos los extremos
del intervalo.
## 25%
## 7.40624
## 75%
## 8.358412
## GSM1085686_HE32H023_2_.CEL
## 7.320905
## GSM1085697_HE32H034.CEL
## 8.364369
20.7 Ejercicios
Ej. 33 — Vamos a realizar distintas representaciones gráficas con
los datos del ejercicio 32. Se pide lo siguiente:
1.Realizar distintos histogramas de los datos que aparecen en el
ejercicio 32 modificando el número de clases. ¿Hay un compor-
tamiento consistente en la representación gráfica?
20.7. EJERCICIOS 319
Ej. 35 — x
22.24 21.04 23.89 22.49 25.22 22.15 22.49 27.51 23.57 25.22 23.47 18.91
21.64 24.29 21.68 24.51 22.32 24.77 18.30 23.03 22.03 21.09 23.32 21.15
21.21 25.53 19.34 25.89 23.06 25.90 20.09 25.65 27.76 29.14 22.88 31.40
22.79 23.68 22.15 21.50 22.40 24.39 20.34 17.53 25.59 20.25 20.76 23.08
20.66 20.47
y
27.60 24.02 33.97 27.84 33.12 37.32 37.53 38.95 29.80 32.72 30.04 26.45
26.34 32.82 28.91 29.37 32.39 29.43 37.83 24.46 37.82 32.19 34.51 32.64
30.44 38.70 29.84 29.35 32.78 34.01 36.24 41.86 35.96 35.57 33.84 27.69
29.32 41.71 34.08 27.64 33.06 39.98 36.62 29.72 33.51 31.49 33.51 33.24
25.02 39.78 31.96 37.69 44.01 29.07 32.94 30.47 33.33 24.34 35.99 32.25
36.51 33.47 35.37 31.82 38.49 25.67 29.36 36.64 24.14 39.54
Se pide:
1.Representar en dos gráficos distintos los estimadores kernel de
ambas densidades.
320 CAPÍTULO 20. ESTADÍSTICA DESCRIPTIVA
Probabilidad
252 252
- Is he in?
Is he in?
Nathe!
21.1 Experimento, suceso y probabilidad He can’t hear you through
your...
Nos movemos constantemente en situaciones en que no podemos triple bloody glazing.
predecir qué va a ocurrir.1 Realizamos un viaje en coche entre dos Script: Full Monty (1997)
ciudades dadas. El tiempo que tardamos en realizar el viaje depende
de muchos factores que hacen incierto el resultado. Nos sometemos
a una operación quirúrgica. El resultado también es incierto. Quizás
los ejemplos más simples y, por ello, los que se suelen utilizar están
asociados con juegos de azar. Lanzamos un dado, el resultado que ob-
tenemos no lo podemos predecir. Y el número de ejemplos es infinito.
Nos encontramos en situaciones en donde no podemos predecir lo que
va a ocurrir.
321
322 CAPÍTULO 21. PROBABILIDAD
Ω = {cara, cruz}.
A = {2, 4, 6}.
A = {4, 5, 6}.
3
P (Mayor o igual a 4) = P ({5, 5, 6}) = .
6
¿Qué probabilidad tenemos de obtener una cara al lanzar una
moneda? Por el mismo razonamiento:
1
P (Cara) = P ({Cara}) = .
2
Un resultado es favorable y dos resultados son posibles cuando
lanzamos la moneda.
Tenemos en R una función que nos sirve para elegir al azar de un
grupo de elementos previamente definidos y de un modo equiprobable
entre los posibles resultados del experimento. Es la función sample.
Ejemplo 21.1 (Lanzamos una moneda muchas veces) Veamos
cómo lanzar una moneda con R. Le decimos cuál es el espacio muestral
Omega = c("cara","cruz")
sample(Omega,1)
## [1] "cruz"
sample(Omega,1)
## [1] "cruz"
sample(Omega,1)
## [1] "cara"
sample(Omega,30,replace=TRUE)
Y otras 30 veces.
sample(Omega,30,replace=TRUE)
Podemos contar cuántas veces nos ha salido cara y cruz (el que
quiera puede hacerlo manualmente).
x = sample(Omega,30,replace=TRUE)
table(x)
## x
## cara cruz
## 16 14
table(x) / 30
## x
## cara cruz
## 0.5333333 0.4666667
x = sample(Omega,100,replace=TRUE)
table(x) / 100
## x
## cara cruz
## 0.52 0.48
x = sample(Omega,1000,replace=TRUE)
table(x) / 1000
## x
## cara cruz
## 0.522 0.478
x = sample(Omega,100000,replace=TRUE)
table(x) / 100000
## x
## cara cruz
## 0.49986 0.50014
## pdf
## 2
sample(Omega,1)
## [1] 3
sample(Omega,20,replace=TRUE)
x = sample(Omega,1000,replace=TRUE)
table(x) / 1000
## x
## 1 2 3 4 5 6
## 0.176 0.168 0.167 0.176 0.147 0.166
12 21 13 31 23 32
n × (n − 1) × . . . × (n − k + 1).
n! = n × (n − 1) × . . . × 1.
21.1. EXPERIMENTO, SUCESO Y PROBABILIDAD 327
12 21
{1,2} {2,1}
factorial(10)
## [1] 3628800
choose(10,5)
## [1] 252
## [1] 1098240
(casosposibles = choose(52,5))
## [1] 2598960
casosfavorables / casosposibles
## [1] 0.422569
(cartas = rep(1:13,4))
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 1 2
## [16] 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4
## [31] 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6
## [46] 7 8 9 10 11 12 13
(mano = sample(cartas,5))
## [1] 11 10 12 8 11
(conteosmano = table(mano))
## mano
## 8 10 11 12
## 1 1 2 1
length(conteosmano)
## [1] 4
nsimulaciones = 1000
exitos = 0
for(i in 1:nsimulaciones){
mano = sample(cartas,5)
conteosmano = table(mano)
if(length(conteosmano) == 4) exitos = exitos + 1
}
exitos / nsimulaciones
## [1] 0.416
2. P (Ω) = 1.
el curso aunque sí que es conveniente. No hay nada tan práctico como la teoría.
330 CAPÍTULO 21. PROBABILIDAD
21.2 Ejercicios
Ejercicio 36
Seis personas se sientan a comer en un restaurante. Hay seis sillas
alrededor de la mesa.
1. ¿De cuántas formas distintas pueden sentarse?
2. Supongamos que las sillas están enfrentadas, tres en un lado de
la mesa y otras tres al otro lado. Además las seis personas son
tres parejas que han quedado a cenar. Siguiendo una antigua
costumbre se sientan a un lado los hombres y al otro lado las
mujeres. ¿De cuántas formas distintas se pueden sentar?
Ejercicio 37
Supongamos el póquer cerrado sin comodines. Calcular la proba-
bilidad de obtener un póquer cuando nos dan una mano.
Ejercicio 38
Consideremos el experimento aleatorio consistente en lanzar dos
veces un dado. Se pide:
1. ¿Qué probabilidad tenemos de obtener dos veces el número 6?
2. ¿Y de obtener el par de valores 1 y 5?
3. ¿Qué probabilidad tenemos de que coincidan el primer y el se-
gundo resultado, esto es, de que el primer lanzamiento sea un
uno y el segundo también o de que el primer lanzamiento sea
un dos y el segundo también, etc?
4. ¿Qué probabilidad tenemos de que la suma de los dos valores
sea 7? ¿Y de que la suma de los dos valores sea mayor o igual
que 7? ¿Y de que sea mayor que 7?
21.3. VARIABLE ALEATORIA 331
X:Ω → R
ω → X(ω) = x.
finito numerable de valores. En fin, detalles técnicos a los que no hay que prestar
demasiado interés en un curso como este.
332 CAPÍTULO 21. PROBABILIDAD
x 0.000 1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000 9.000 10.000
P (X = x) 0.107 0.268 0.302 0.201 0.088 0.026 0.006 0.001 0.000 0.000 0.000
Tabla 21.1: Función de probabilidad de una variable discreta. En la primera fila el valor y en la segunda la probabilidad
de tomar este valor.
21.3.2 Ejercicios
Ejercicio 39
Consideremos el experimento aleatorio consistente en lanzar dos
veces un dado. Un resultado del experimento puede ser ω = (1, 3)
indicando que en primer lugar hemos obtenido un 1 y en el segundo
lanzamiento hemos obtenido un 3. Consideramos la variable aleatoria
que asocia al resultado obtenido la suma de los valores que obtene-
mos en el primer y en el segundo lanzamiento. Si ω = (i, j) entonces
X(ω) = i + j.
1. Indicar qué valores puede tomar la variable X.
2. Obtener la función de probabilidad de la variable X.
3. Obtener las probabilidades siguientes: P (X ≤ 1), P (X ≤ 2), P (X >
2), P (X ≤ 4), P (4 ≤ X ≤ 6), P (4 < X ≤ 6), P (4 ≤ X < 6).
21.3. VARIABLE ALEATORIA 333
{
0≤x≤1
1.00
1 si
f (x) =
0 si x < 0 ó x > 1.
0.75
0.25
∫ b ∫ b
P (a ≤ X ≤ b) = f (x)dx = dx = b − a,
a a
0.00
runif(1,min=0,max=1)
## [1] 0.6736497
runif(20,min=0,max=1)
{ 1
b−a si a≤x≤b
f (x) =
0.2
0 en otro caso.
∫ ∫
d d
1 d−c
Figura 21.4: Función de densidad P (c ≤ X ≤ d) = f (x)dx = dx = .
de una variable uniforme en el in- c c b−a b−a
tervalo [2, 5].
Otra vez la probabilidad de que el valor aleatorio de X esté en el
intervalo [c, d] solamente depende de lo largo que es el intervalo y no
de dónde está dentro de [a, b].
4 Más no que ocupa demasiado espacio. En cualquier caso podemos probar a
21.3.4 Ejercicios
Ej. 40 — Consideremos una variable aleatoria uniforme en el inter-
valo [0, 1]. Se pide:
1.¿Qué probabilidad tenemos de que la variable sea menor o igual
que 0.5? En otras palabras: ¿cuánto vale P (X ≤ 0.5)?
2.¿Y P (X < 0.5)?
3.Calcular P (X ≥ 0.5) y P (X > 0.5).
4.Determinar las siguientes probabilidades: P (0.6 < X ≤ 0.9),
P (0.6 ≤ X < 0.9) y P (0.6 ≤ X ≤ 0.9).
0.2 ●
∫ x 0.0
●
● ● ● ●
−∞
Figura 21.5: Probabilidades de la
En general se tiene la siguiente importante igualdad. tabla 21.1.
0.4
●
0.2
●
0.0
0 2 4 6 8 10
x
336 CAPÍTULO 21. PROBABILIDAD
●
●
●
●
●
●
tribución muestral. La primera es la función ecdf y podemos verla en
la figura 21.7.
0.8
●
●
●
●
●
●
●
●
0.6
●
●
●
Fn(x)
●
●
●
●
●
plot(ecdf(y))
0.4
●
●
●
●
●
●
●
●
0.2
●
●
ecdf(y)(37)
Figura 21.7: Función de distribu-
ción muestral con la función ecdf. ## [1] 1
o bien en 40,
ecdf(y)(40)
## [1] 1
library(Hmisc)
0.6
Ecdf(y)
0.4
0.2
0.0
x 0.00 1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00
P (X = x) 0.20 0.11 0.13 0.24 0.27 0.02 0.01 0.01 0.00 0.01
Tabla 21.2: Función de probabilidad de la variable aleatoria que nos da el número de personas que residen en una
vivienda.
x = 0:9
probabilidades = c(0.20,0.11,0.13,0.24,0.27,0.02,0.015,0.009,
0.0009,0.0051)
sample(x,size=1,replace=TRUE,prob=probabilidades)
## [1] 4
n = 100
(y = sample(x,size=n,replace=TRUE,prob=probabilidades))
## [1] 2 9 1 4 2 3 4 0 4 1 3 3 0 1 3 4 4 4 9 0 2 4
## [23] 1 3 3 1 4 4 4 2 4 3 6 0 3 4 3 2 1 3 4 3 4 4
## [45] 7 1 0 4 0 3 2 0 3 5 2 3 4 0 2 4 4 3 1 3 0 3
## [67] 4 3 4 3 2 2 3 4 3 4 3 4 4 1 3 0 2 3 0 3 4 3
## [89] 2 4 0 3 4 4 4 2 4 4 4 0
prop.table(table(y))
## y
## 0 1 2 3 4 5 6 7 9
## 0.13 0.09 0.13 0.27 0.33 0.01 0.01 0.01 0.02
y = sample(x,size=1000,replace=TRUE,prob=probabilidades)
prop.table(table(y))
## y
## 0 1 2 3 4 5 6 7
## 0.190 0.100 0.133 0.259 0.265 0.023 0.013 0.008
## 8 9
## 0.002 0.007
## [1] 2.4761
y
En el eje de abscisas consideramos el número de valores que vamos 1
∑
+∞ Figura 21.9: Medias muestrales
EX = µX = µ = xi P (X = xi ). del número de personas que ha-
bitan una vivienda en función del
i=1
tamaño de la muestra. La línea
Ejemplo 21.9 Lanzamos la moneda si sale cara la variable X vale horizontal punteada indica la me-
uno y si sale cruz la variable X vale cero. ¿Cuál es su media? dia poblacional.
µ = 1 × p + 0 × (1 − p) = p.
X(ω) = 1A (ω),
X ∼ Bi(1, p).
X ∼ Bi(n, p).
Observemos que los valores que puede tomar esta variable son 0, 1, 2, . . . , n,
esto es, desde cero éxitos hasta n éxitos. ¿Qué probabilidad tenemos
de observar un número determinado de éxitos? Esta probabilidad,
P (X = x) es la función de probabilidad de la binomial y se prueba
que tiene la siguiente expresión.
( )
n x
P (X = x) = p (1 − p)n−x . (21.10)
x
∑n ( )
n x
EX = µ = x p (1 − p)n−x = np, (21.11)
x=0
x
∑
n ( )
n x
var(X) = σ 2 = (x − np)2 p (1 − p)n−x = np(1 − p). (21.12)
x=0
x
dbinom(70,size=123,prob=0.5)
## [1] 0.02230619
rbinom(30,size=1,prob=.5)
## [1] 1 0 1 1 0 0 1 1 0 1 1 0 1 1 0 1 0 1 1 1 1 0 1
## [24] 1 1 1 0 1 0 0
rbinom(30,size=1,prob=.5)
## [1] 0 0 1 0 1 0 0 1 0 1 1 1 0 0 1 0 0 1 0 0 1 0 1
## [24] 1 0 1 1 1 1 0
rbinom(1,size=30,prob=.5)
## [1] 16
rbinom(1,size=30,prob=.5)
## [1] 16
rbinom(40,size=30,prob=.5)
## [1] 19 14 14 14 16 16 14 17 12 13 14 20 19 16 14
## [16] 17 11 22 13 13 15 15 16 16 17 13 20 18 11 13
## [31] 12 8 12 18 17 17 12 13 15 18
rbinom(40,size=30,prob=.6)
## [1] 18 20 17 21 20 20 24 20 19 17 22 22 16 17 15
## [16] 14 20 20 19 19 17 18 20 21 18 18 17 13 19 14
## [31] 19 17 17 22 20 15 25 18 18 17
dbinom(23,size=30,prob=.6)
## [1] 0.02634109
dbinom(0:30,size=30,prob=.6)
y
## [19] 1.473752e-01 1.396186e-01 1.151854e-01
## [22] 8.227527e-02 5.048710e-02 2.634109e-02
0.05 ●
●
●
● ● ● ● ●
0.00
## [31] 2.210739e-07 0 10 20 30
x
En la figura 21.10 tenemos la representación gráfica de estas pro- Figura 21.10: Para una variable
babilidades. binomial con n = 30 y una proba-
También podemos obtener la función de la distribución binomial bilidad de éxito de p = 0.6 mos-
tramos la función de probabilidad
en cualquier punto, es decir, la probabilidad P (X ≤ 12) es que para cada x nos da la proba-
bilidad de que la variable tome ese
0.20
5 10
Ej. 45 — Se pide:
1.Simular 100 valores con distribución binomial con 20 pruebas y Figura 21.11: Función de densidad
una probabilidad de éxito en cada prueba de 0.3. Guardar estos de una normal con media 7 y va-
rianza 4.
valores en el vector x.
1.00 ● ● ● ● ● ● ●
0.50
nes por 1000, por 10000 y por 100000. Comparar en cada caso 0.25
●
●
●
0.00 ● ● ● ● ● ● ● ● ● ● ● ●
1.P (X ≤ 23).
2.P (X < 23).
3.P (X > 29).
4.P (X ≥ 29).
5.P (34 < X ≤ 45).
6.P (34 ≤ X ≤ 45).
X ∼ P o(λ).
X ∼ P o(λ).
e−λ λx
lim P (Xn = x) = .
n→+∞ x!
Demostración 21.1 Consideremos la sucesión de variables aleato-
rias Xn ∼ Bi(n, pn ) en la que a medida que n aumenta, pn disminuye
de forma tal que npn ≈ λ. Más concretamente, npn → λ. Tendremos
para la función de probabilidad que
( )
n x n!
P (Xn = x) = p (1 − pn )n−x = px (1 − pn )n−x ,
x n x!(n − x)! n
y para n suficientemente grande,
( )x ( )n−x
n! λ λ
P (Xn = x) ≈ 1−
x!(n − x)! n n
( )n ( )−x
λ n(n − 1) · · · (n − x + 1)
x
λ λ
= 1 − 1 − .
x! nx n n
8 Es fácil comprobar que la función que acabamos de considerar en 21.14 es de
probabilidad. Es no negativa y
∑
+∞
λx ∑ λx
+∞
e−λ = e−λ = e−λ eλ = 1.
x=0
x! x=0
x!
Al pasar al límite,
( )n ( )−x
n(n − 1) · · · (n − x + 1) λ λ
→ 1, 1− → e−λ , 1− → 1,
nx n n
y tendremos
e−λ λx
lim fXn (x) = .
n→+∞ x!
La utilidad de este resultado reside en permitir la aproximación de la
función de cuantía de una binomial con n pruebas y probabilidad de
éxito p, Bi(n, p), mediante la función de cuantía de una Poisson con
párametro λ = np cuando n es grande y p pequeño.
Se demuestra que
pr
E(X) = µ = , (21.17)
1−p
y que su varianza viene dada por
pr
var(X) = σ 2 = . (21.18)
(1 − p)2
Γ(k + r) k
P (X = k) = p (1 − p)r (21.19)
k!Γ(r)
con k = 0, 1, . . .
En lo anterior hemos parametrizado la familia utilizando k y r. Su-
pongamos que parametrizamos utilizando µ y r. Tendremos entonces
p = µ/(r + µ) y sustituyendo
( )k ( )r
Γ(k + r) µ r
P (X = k) = . (21.20)
k!Γ(r) r + µ r+µ
f (x) = √ e− 2 σ 2 (21.23)
2πσ
De otro modo, si tomamos dos valores arbitrarios a y b con a ≤ b
entonces ∫ b
P (a ≤ X ≤ b) = f (x)dx.
a
1
f (x) = √ e− 2 x .
1 2
(21.24)
0.3
2π
Densidad
0.2
−6 −4 −2 0 2 4 6
esto es, la función que para cada valor z nos da la probabilidad de que
x
la variable sea menor o igual que este valor z es la siguiente
∫ z
1
√ e− 2 x dx.
1 2
Figura 21.13: Función de densidad Φ(z) = (21.25)
de una normal estándar o típica. −∞ 2π
Dado un punto z el valor de la función Φ(z) nos da el área bajo la
curva de la densidad normal entre −∞ y el punto z. En la figura 21.14
hemos rayado en negro esta zona para z = 1.3
Hay tablas que nos proporcionan el valor de esta función para di-
ferentes valores de z.11 Esto era necesario cuando no teníamos herra-
mientas informáticas. Ahora lo lógico es utilizar software. En concreto
0.4
el valor de Φ(1.3) (área de la zona rayada en negro en la figura 21.14
lo obtendríamos con R del siguiente modo.
0.3
pnorm(1.3)
Densidad
0.2
## [1] 0.9031995
0.1
En la figura 21.15 tenemos representada la función Φ.
10 También
se denota con frecuencia X ∼ N (µ, σ), es decir, se indica la media
0.0
µ y la desviación típica o estándar σ.
−6 −3 0 3 6
x
11 Simplemente poniendo en Google “tablas de la normal” nos aparecen un mon-
tón de tablas. Cualquier libro de texto de hace unos años lleva al final del texto
Figura 21.14: La función de distri- unas tablas de la normal.
bución de la normal estándar en el
punto 1.3 corresponde con el área
de la zona rayada.
1.00
0.75
21.9. DISTRIBUCIÓN NORMAL 349
X −µ
Z= ∼ N (0, 1). (21.26)
σ 0.3
12
Esta transformación recibe el nombre de tipificación o estandari- 0.2
Nota 21.3 (De cómo calculaban los antiguos las probabilidades con la normal) 0 10 20
b−µ a−µ
P (a ≤ X ≤ b) = Φ −Φ , (21.28) 0.05
σ σ
∫ b (x−µ)2
∫ b−µ
1 −1 σ 1 1 2 Figura 21.17: Densidad de una
√ e2 σ2 dx = √ e− 2 x dx.
a 2πσ a−µ 2π N (56, 9). El área de la zona raya-
σ
da en negro corresponde a la pro-
babilidad de que la variable esté
entre 60 y 63.
350 CAPÍTULO 21. PROBABILIDAD
## [1] 0.1209854
x0 = seq(10,22,1)
dnorm(x0,mean= 16, sd= 2)
10 20 30 40
## [1] 0.1586553
0.25
Podemos representar esta función (figura 21.19).
También podemos plantear el problema inverso. Consideramos una
0.00
10 15 20
probabilidad, por ejemplo 0.34, y buscamos el valor de x donde P (X ≤
x
x) = 0.34 o dicho de otro modo el percentil de orden 0.34.
Figura 21.19: Función de distribu-
ción (acumulada) de la distribu- qnorm(0.34,mean= 16, sd= 2)
ción normal con media 16 y des-
viación estándar 2. ## [1] 15.17507
−∞ 2π −∞ 2π
Vamos a calcular la diferencia anterior utilizando R.
pnorm(1,mean=0,sd=1) - pnorm(-1,mean=0,sd=1)
## [1] 0.6826895
P (µ − σ ≤ X ≤ µ + σ) = 0.6826895. (21.31)
pnorm(2,mean=0,sd=1) - pnorm(-2,mean=0,sd=1)
## [1] 0.9544997
que es igual a
pnorm(3,mean=0,sd=1) - pnorm(-3,mean=0,sd=1)
## [1] 0.9973002
P (µ − σ ≤ X ≤ µ + σ) 0.6826895
P (µ − 2σ ≤ X ≤ µ + 2σ) 0.9544997
P (µ − 3σ ≤ X ≤ µ + 3σ) 0.9973002
21.10 Ejercicios
Ej. 49 — Se pide:
1.Simular 100 valores con distribución normal con media 20 y des-
viación típica 3. Guardar estos valores en el vector x.
2.Calcular la media y varianza muestrales de los valores generados.
3.Comparar la media muestral observada con 20 y la varianza
muestral observada con 9 que corresponden con la media y la
varianza teóricas.
4.Repetir los apartados anteriores sustituyendo las 100 simulacio-
nes por 1000, por 10000 y por 100000. Comparar en cada caso
los valores teóricos con los valores muestrales.
Distribución muestral
N=2374560
X = rbinom(N,size=1,prob=.034)
353
354 CAPÍTULO 22. DISTRIBUCIÓN MUESTRAL
X[1:10]
## [1] 0 0 0 0 0 0 0 0 0 0
X[100000]
## [1] 0
n = 100
x = sample(X,n)
x
## [1] 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
## [23] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
## [45] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
## [67] 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
## [89] 0 0 0 0 0 0 0 0 0 0 0 0
sum(x)
## [1] 4
x = sample(X,100)
sum(x)
## [1] 2
## [1] 3 5 5 2 3 2 3 7 6 4 4 0 4 4 2 4 6 3 3 2
sumas/n
## [1] 0.03 0.05 0.05 0.02 0.03 0.02 0.03 0.07 0.06
## [10] 0.04 0.04 0.00 0.04 0.04 0.02 0.04 0.06 0.03
## [19] 0.03 0.02
22.2.1 Ejercicios
Ej. 51 — 254 Muchos equipos de investigación pretenden realizar un 254 [152, pág. 79, problemas
estudio sobre el porcentaje de personas que tienen cáncer de colon. 2-3]
Si una muestra aleatoria de diez personas se pudo obtener, y si la
probabilidad de probabilidad de tener cáncer de colon es 0.05, ¿cuál
es la probabilidad de que un equipo de investigación obtenga p̂ = 0.1?
¿Y la de p̂ = 0.05?
Ej. 53 — 256 Imaginemos que un millar de equipos de investigación 256 [152, pág. 80, problemas
extraen una muestra al azar de una distribución binomial con p = 0.4, 6-7]
cada estudio está basado en una muestra de tamaño 30. Tendremos
1000 valores de p̂. Si promediamos estos 1000 valores: ¿Cuál sería
aproximadamente el resultado? Si calculamos la varianza muestral de
los valores de p̂: ¿Cuál sería aproximadamente el resultado?
N = 237456
X = rnorm(N,mean=160,sd=10.23)
X[1:10]
count
La figura 22.1 tenemos un histograma de toda la población. La
figura 22.2 tiene un estimador kernel de la densidad de probabilidad. 10000
(mu=mean(X)) X
la función sample.
0.03
n = 100
x = sample(X,n)
density
0.02
mean(x) 0.00
## [1] 157.9384
Figura 22.2: Estimador kernel de
la densidad de las alturas.
Si repetimos la selección de los individuos y el cálculo de la media
muestral tenemos
x = sample(X,n)
mean(x)
## [1] 158.9058
160.0
muestrales están mucho más próximas a la media poblacional.
Finalmente supongamos que tomamos muestras de tamaño cre-
159.5
ciente y mostramos en abscisas el tamaño de la muestra y en ordena-
159.0
das la media muestral observada. En la figura 22.3 tenemos el resulta-
do. Lo repetimos. En la figura ?? tenemos las medias observadas. No
158.5
√ X̄n − µ
n ∼ N (0, 1) (22.2)
σ
Nos interesa conocer probabilidades como
P (X̄ ≤ b)
P (a ≤ X̄ ≤ b)
Ejemplo 22.2 Por ejemplo, supongamos que nos interesa saber qué
probabilidad tiene la media muestral de ser menor que 162. Como
estamos suponiendo que conocemos toda la población podemos tomar
como varianza la de toda la población.
sigma = sd(X)
pnorm(162,mean=mu,sd=sigma/sqrt(n))
## [1] 0.9741615
pnorm(162,mean=mu,sd=sigma/sqrt(n)) -
pnorm(159,mean=mu,sd=sigma/sqrt(n))
## [1] 0.8135001
1 - pnorm(160,mean=mu,sd=sigma/sqrt(n))
## [1] 0.5050096
Si ∫ x
1 (t − µ)2
Φ(x) = √ exp − dt.
−∞ 2πσ 2σ 2
lo que estamos haciendo con R es simplemente aplicar que
P (X̄ ≤ b) = Φ(b)
o
P (a ≤ X̄ ≤ b) = Φ(b) − Φ(a)
o
P (a ≤ X̄) = 1 − Φ(a)
358 CAPÍTULO 22. DISTRIBUCIÓN MUESTRAL
22.3.1 Ejercicios
Ej. 54 — 257 Supongamos n = 16, σ = 2 y µ = 30. Supongamos 257
[152, pág. 84, problema 8]
normalidad. Determinar:
1.P (X̄ ≤ 29),
2.P (X̄ > 30.5),
3.P (29 ≤ X̄ ≤ 31).
258
[152, pág. 84, problemas Ej. 55 — 258 Alguien dice que dentro de un determinado barrio, el
10-11] coste medio de una casa es de µ = 100000 euros con una desviación es-
tándar de σ = 10.000 euros. Supongamos que, basándonos en n = 16
viviendas, observamos una media muestral X̄ = 95.000. Suponiendo
normalidad, ¿cuál es la probabilidad de obtener una media muestral
como la observada o menor si las afirmaciones sobre la media y desvia-
ción estándar son verdaderas? ¿Y la probabilidad de tener una media
muestral entre 97500 y 102500 euros?
259
[152, pág. 85, problema Ej. 56 — 259 Supongamos que eres un profesional de la salud in-
13] teresado en los efectos de la medicació en la presión arterial diastólica
de las mujeres adultas. Para un medicamento en particular que es-
tá siendo estudiado, se encuentra que para n = 9 mujeres, la media
muestral es X̄ = 85 y la varianza muestral es s2 = 160.78. Estimar
el error estándar de la media muestral asumiendo que tenemos una
muestra aleatoria.
260
[152, pág. 85, problema Ej. 57 — 260 Una compañía afirma que las primas pagadas por sus
12] clientes para el seguro de automóviles tiene una distribución normal
con media µ = 750 euros y desviación estándar σ = 100 euros. Su-
poniendo normalidad, ¿cuál es la probabilidad de que para n = 9
clientes elegidos al azar, ¿la media muestral tome un valor entre 700
y 800 euros?
p̂ − p
Z=√ . (22.3)
p(1 − p)/n
22.4. DISTRIBUCIÓN MUESTRAL DE LA MEDIA EN POBLACIONES NO NORMALES. TEOREMA
P (a ≤ p̂ ≤ b) =
P (p̂ ≤ b) − P (p̂ ≤ a) =
b−p a−p
P (Z ≤ √ ) − P (Z ≤ √ ). (22.4)
p(1 − p)/n p(1 − p)/n
22.4.3 Ejercicios
Ej. 58 — 1.Supongamos una distribución binomial con p = 0.5
y n = 10 y queremos calcular la probabilidad de que p̂ sea menor
o igual a 7/10. Obtener el valor exacto y el valor aproximado
utilizando la aproximación dada por el teorema central del límite.
2.Repetir el punto anterior obteniendo el valor exacto y el valor
aproximado de P (0.3 ≤ p̂ ≤ 0.7).
Estimación
23.1 Introducción
Tratamos el problema de la estimación. En concreto, en poblacio-
nes normales, nos planteamos la estimación de la media y varianza.
También consideramos la estimación de una proporción. Se aborda
el problema del cálculo del tamaño de la muestra para estimar los
parámetros con un error máximo dado.
23.2 La población
¿Qué es una población? La Estadística se ocupa del estudio de
grandes poblaciones. Pero, otra vez, ¿y qué es una población? La
respuesta no es simple ni tampoco es única.
El primer sentido que podemos dar al término población es una
gran colección de elementos de los cuales queremos conocer algo. Al-
gunos ejemplos son:
361
362 CAPÍTULO 23. ESTIMACIÓN
(mu=mean(X))
## [1] 159.9931
n = 10
(x = sample(X,n))
1 Hemos tenido la santa paciencia de medir la estatura de cada uno de ellos. Y
(mediamuestral = mean(x))
## [1] 160.8276
mediamuestral - mu
## [1] 0.834481
errores = estimaciones-mu
summary(errores) 0.20
## Max.
density
## 4.50297 0.10
∑
n
Xi
µ̂ = X̄n = .
i=1
n
qnorm(0.975,mean=0,sd=1)
## [1] 1.959964
En resumen que
( )
√ X̄ − µ
P − 1.96 ≤ n ≤ 1.96 = 0.95
σ
o, lo que es equivalente,
( )
σ σ
P X̄ − 1.96 √ ≤ µ ≤ X̄ + 1.96 √ = 0.95.
n n
Vemos que el intervalo [X̄ − 1.96 √σn , X̄ + 1.96 √σn ] tiene una probabi-
lidad de 0.95 de contener a µ o también de cubrir a µ. Si ahora susti-
tuimos los valores aleatorios Xi con i = 1, . . . , n con los valores obser-
vados en la muestra entonces el intervalo aleatorio [X̄ − 1.96 √σn , X̄ +
1.96 √σn ] pasa a ser un intervalo fijo [x̄ − 1.96 √σn , x̄ + 1.96 √σn ] que
conocemos como intervalo de confianza con nivel de confianza 0.95.
Nota de R 23.1 (Intervalo de confianza con R) Vamos a eva-
luarlo con R. Empezamos tomando los datos.
(x = sample(X,10))
media = mean(x)
s = sd(x)
## [1] 158.6343
## [1] 164.9894
alpha = 0.01
## [1] 157.6359
y el superior
## [1] 165.9879
El intervalo es el siguiente:
23.6. INTERVALO DE CONFIANZA PARA LA MEDIA 367
c(extremo.inferior,extremo.superior)
El último paso es rogar a Dios que las cosas hayan ido bien. Te-
nemos una confianza de 1 − α (0.99 en el ejemplo) de que el valor
real de la media esté en este intervalo. Pero esto no quiere decir que
realmente lo está. Si repetimos un gran número de veces el valor real
de la media está en el intervalo un (1−α)×100 % de la veces (un 99%
en el ejemplo) pero puede ocurrir (desgracias de la vida) que estemos
en el α × 100 (en el ejemplo un 1%) restante. En general la cosa va
bien porque elegimos un nivel de confianza grande (próximo a uno)
pero no siempre va bien.
√ X̄ − µ
∼ tn−1 .
0.3
T = n (23.3)
S
dt(u, df = 9)
0.2
−3 −2 −1 0 1 2 3
3 ¿Van por ahí los datos diciendo somos normales no te decimos la media pero
Vemos que tienen una forma similar, ambas están centradas en cero.
0.2
−3 −2 −1 0 1 2 3
¿Qué ocurre cuando incrementamos el número de grados de liber-
x tad? Cuando se va incrementando el número de grados la densidad de
la t de Student se aproxima a la densidad de la normal. En la figura
Figura 23.3: Funciones de densi- 23.4 se ilustra y comenta este hecho.
dad de la normal estándar (tra-
zo continuo) y de densidades t de Y ahora vamos a repetir lo visto en la sección anterior sustituyendo
Student con 2 grados de libertad.
a la normal estándar con la densidad de la t de Student con n-1
grados de libertad. Dada una probabilidad, por ejemplo 0.95, podemos
determinar el valor c tal que
0.4
P (−c ≤ T ≤ c) = 0.95.
0.3
P (T ≤ c) = 0.975
0.1
−3 −2 −1 0 1 2 3
con
x
qt(0.975,df=9)
Figura 23.4: Funciones de densi-
dad de la normal estándar (tra- ## [1] 2.262157
zo continuo) y de densidades t de
Student con 2, 7 y 12 grados de Denotamos el valor de c tal que
libertad. Según el número de gra-
dos de libertad de la t es mayor α
más se aproxima la densidad de la
P (T ≤ c) = 1 − ,
2
t a la normal. Por ello, la más ale-
jada es la t(2) y la más próxima como tn−1,1−α/2 . Entonces
es la t(12).
S S
P (X̄ − tn−1,1−α/2 √ ≤ µ ≤ X̄ + tn−1,1−α/2 √ ) = 1 − α. (23.4)
n n
El intervalo de confianza lo obtenemos sustituyendo los valores alea-
torios por los valores observados.
Teorema 23.1 Si suponemos que tenemos una muestra aleatoria de
datos normales X1 , . . . , Xn y observamos los datos X1 = x1 , . . . , Xn =
xn entonces el intervalo
[ ]
s s
x̄ − tn−1,1−α/2 √ , x̄ + tn−1,1−α/2 √
n n
es un intervalo de confianza con nivel de confianza 1−α para la media
µ. De un un modo abreviado el intervalo anterior se puede escribir
como
s
x̄ ± tn−1,1−α/2 √
n
23.6. INTERVALO DE CONFIANZA PARA LA MEDIA 369
alpha = 0.01
## [1] 156.5431
y el superior
## [1] 167.0806
El intervalo es el siguiente
c(extremo.inferior,extremo.superior)
alpha = 0.05
t.test(x,conf.level=1-alpha)
##
## One Sample t-test
##
## data: x
## t = 99.808, df = 9, p-value = 5.161e-15
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## 158.1444 165.4793
## sample estimates:
## mean of x
## 161.8119
alpha = 0.05
t.test(x,conf.level=1-alpha)$conf.int
Intervalos de confianza
Ejemplo 23.1 (Datos gse21942) Vamos a utilizar los datos tami-
data::gse21942.
Figura 23.5: Intervalos de confian-
za de la media en una población library(Biobase)
normal. Hemos simulado 100 in- data(gse21942,package="tamidata")
tervalos. La línea vertical tiene co- y = exprs(gse21942)[54651,]
mo abscisa el valor real de la me-
dia. ¿Cuántos intervalos no con- x = pData(gse21942)[,"FactorValue..DISEASE.STATE."]
tienen a la media real? Cuéntalos. y0 = y[x == "multiple sclerosis"]
t.test(y0)
##
## One Sample t-test
##
## data: y0
## t = 7.5787, df = 13, p-value = 4.023e-06
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## 3.517188 6.321905
## sample estimates:
## mean of x
## 4.919546
y0.t = t.test(y0)
y0.t$conf.int
o simplemente
t.test(y0)$conf.int
t.test(y0,conf.level=.90)$conf.int
t.test(y0,conf.level=.99)$conf.int
media = 5.021
desviacion.estandar = 2.077
n = 4499
alpha = .01
(extremoinferior = media - qt(1-alpha/2,df=n-1) *
desviacion.estandar/ sqrt(n))
## [1] 4.941204
## [1] 5.100796
media = 4.969
desviacion.estandar = 1.909
n = 1724
6 No es tan extraña esta situación. Con frecuencia cuando lees un informe o
bien un artículo científico no sueles disponer de los datos originales sino de los
resúmenes que de los mismos proporcionan los autores en la publicación. Tiene
sentido e interés ver cómo calcular estos intervalos a partir de los datos resumidos.
372 CAPÍTULO 23. ESTIMACIÓN
Tabla 23.1: Resumen de los resultados de Matemáticas II. Las etiquetas indican: Matric., matriculados; Pre-
sent.,presentados; Aptos, aptos; Media, nota media; DE, desviación estándar; Present. FG, presentados fase general;
Present. FE, presentados fase específica; Aprob. FE, aprobados fase específica; Media FG, media fase general; DE
FG, desviación típica fase general; Media FE, media fase específica; DE FG, desviación típica fase específica. En filas
tenemos las universidades de Alicante (UA), la Jaume I de Castellón (UJI), la Miguel Hernández de Elche (UMH),
la Universidad de Valencia (UV) y todos los estudiantes en el Sistema de Universidades Valencianas (SUV).
alpha = .01
(extremoinferior =
media - qt(1-alpha/2,df=n-1) * desviacion.estandar/ sqrt(n))
## [1] 4.850441
(extremosuperior =
media + qt(1-alpha/2,df=n-1) * desviacion.estandar / sqrt(n))
## [1] 5.087559
media = 5.054
desviacion.estandar = 2.174
n = 2775
alpha = .01
(extremoinferior = media - qt(1-alpha/2,df=n-1) *
desviacion.estandar/ sqrt(n))
## [1] 4.947624
## [1] 5.160376
t.test(y0,conf.level=.95)$conf.int
mean(y0)
## [1] 4.919546
## [1] 2.804717
y0.ci = t.test(y0,conf.level=.95)$conf.int
(y0.ci[2] - y0.ci[1]) / 2
## [1] 1.402359
length(y0)
## [1] 14
alpha = .05
n = length(y0)
qt(1-alpha/2,df=n-1)*sd(y0)/sqrt(n)
## [1] 1.402359
sd0 = sd(y0)
delta = 0.2
m = n + 10
qt(1-alpha/2,df=m-1)*sd(y0)/sqrt(m)
## [1] 1.0256
m = n + 100
qt(1-alpha/2,df=m-1)*sd(y0)/sqrt(m)
## [1] 0.4506785
m = n + 90
qt(1-alpha/2,df=m-1)*sd(y0)/sqrt(m)
## [1] 0.4723448
for(m in 80:95)
print(c(m,qt(1-alpha/2,df=m-1)*sd(y0)/sqrt(m)))
∑
n
(Xi − X̄n )2 (n − 1)S 2
= ∼ χ2n−1 .
σ2 σ2
0.10
i=1
0.08
2
Estamos diciendo que la variable aleatoria (n−1)S tiene una distribu-
dchisq(x, df = 10)
σ2
0.06
P (X ≤ χ2p,k ) = p.
0.10
0.08
0.06
p = 0.75
0.04
k = 13
0.02
qchisq(p,df=k)
0.00
0 10 20 30 40 50
x
## [1] 15.98391
Y por lo tanto,
( )
(n − 1)S 2 (n − 1)S 2
P ≤ σ 2
≤ = 1 − α.
χ21−α/2,n−1 χ2α/2,n−1
7 La densidad de una distribución ji-cuadrado con k grados de libertad es
1 k x
f (x) = x 2 −1 e− 2 para x ≥ 0 y cero en otro caso.
2k/2 Γ(k/2)
23.8. ESTIMACIÓN DE LA VARIANZA EN POBLACIONES NORMALES377
Es decir el intervalo
[ ]
(n − 1)S 2 (n − 1)S 2
,
χ21−α/2,n−1 χ2α/2,n−1
n = 100
x = sample(X,100)
alpha = .05
s2 = var(x)
(extremoinferior = (n-1)*s2 / qchisq(1-alpha/2,df=n-1))
## [1] 21.71652
## [1] 38.01578
Contraste de hipótesis
24.1 Introducción
Se introduce el problema del contraste de hipótesis en una pobla-
ción.
En concreto, vamos a asumir que tenemos una muestra aleatoria
de una distribución normal, X1 , . . . , Xn , variables aleatorias indepen-
dientes y con una misma distribución. La distribución común que
asumimos es normal con media µ y varianza σ 2 . Es decir, estamos
asumiendo que
Xi N (µ, σ 2 )
y que los distintos valores son independientes entre si.
En este tema nos planteamos el problema del contraste de hipó-
tesis y lo estudiamos estudiando, fundamentalmente, los contrastes
sobre la media µ de la variable que observamos (concentración de
contaminante, nivel de radiación o de ruido).
Asumimos normalidad en los datos con los que trabajamos. Pero:
¿es razonable está hipótesis? Nos ocupamos al final de este tema de
lo que se conoce como contrastes de normalidad.
379
380 CAPÍTULO 24. CONTRASTE DE HIPÓTESIS
H0 : µ ≤ 1500,
H1 : µ > 1500,
X̄n − 1500
T = √ . (24.1)
S/ n
## [1] 3.337196
T ≥c
X̄n − 1500
T = √ ∼ tn−1 . (24.3)
S/ n
P (T ≥ c) = 0.05, (24.4)
o, equivalentemente, que
qt(.95,df=99)
## [1] 1.660391
t0
## [1] 3.337196
## pdf
## 2
Realidad
Decisión H0 H1
Rechazamos H0 Error tipo I
No rechazamos H0 Error tipo II
H0 : µ ≤ µ0 ,
H1 : µ > µ0 .
pasen y asumirlas.
24.2. CONSTRASTES PARA UNA MUESTRA 383
p = P (T ≥ t0 )dondeT ∼ tn−1 .
(pvalor=1-pt(t0,df=n-1))
## [1] 0.0005965143
## pdf
## 2
data(gse21942,package="tamidata")
y = exprs(gse21942)[54651,]
x = pData(gse21942)[,"FactorValue..DISEASE.STATE."]
y0 = y[1:14]
H0 : µ ≥ 6,
H1 : µ < 6.
n = 14
mu0 = 7
(t0 = (mean(y0) - mu0) / (sd(y0)/sqrt(n)))
## [1] -3.204991
alpha = 0.05
qt(alpha,df=n-1)
## [1] -1.770933
t.test(y0,mu=mu0,alternative="less")
##
## One Sample t-test
##
## data: y0
## t = -3.205, df = 13, p-value = 0.00345
## alternative hypothesis: true mean is less than 7
## 95 percent confidence interval:
## -Inf 6.069111
## sample estimates:
## mean of x
## 4.919546
H0 : µ = µ0 ,
H1 : µ ̸= µ0 .
t.test(y0,alternative="two.sided",mu=5)
##
## One Sample t-test
##
## data: y0
## t = -0.12394, df = 13, p-value = 0.9033
## alternative hypothesis: true mean is not equal to 5
## 95 percent confidence interval:
## 3.517188 6.321905
## sample estimates:
## mean of x
## 4.919546
Realizamos el contrate.
t.test(y0,alternative="two.sided",mu=7)
##
## One Sample t-test
##
## data: y0
## t = -3.205, df = 13, p-value = 0.006901
## alternative hypothesis: true mean is not equal to 7
## 95 percent confidence interval:
## 3.517188 6.321905
## sample estimates:
## mean of x
## 4.919546
24.3. INTERVALO DE CONFIANZA Y CONTRASTE DE HIPÓTESIS387
H0 : µ = µ0 ,
H1 : µ ̸= µ0
H0 : θ = θ 0 ,
H1 : θ ̸= θ0
Ejemplo 24.5 Vamos a ilustrar con los datos del ejemplo 24.3. Re-
cuperamos el contraste de si la media sobre los individuos enfermos
es 5.
t.test(y0,alternative="two.sided",mu=5,conf.level=0.95)
##
## One Sample t-test
##
## data: y0
## t = -0.12394, df = 13, p-value = 0.9033
## alternative hypothesis: true mean is not equal to 5
388 CAPÍTULO 24. CONTRASTE DE HIPÓTESIS
Quizás una formulación más formalista del contraste puede ser la si-
guiente donde X es el valor aleatorio que estamos observando n veces.
(a) (b)
(c) (d)
Figura 24.3: Datos x: histograma (a) y estimador kernel de la densidad de x (b). Datos y: histograma (c) y estimador
kernel de la densidad de x (d).
es cierto que
X ∼ N (µ, σ 2 ), (24.9)
2
para algún µ y algún σ . Supongamos que es cierta la afirmación, supo-
nemos cierta que la variable sigue una distribución normal. Elegimos
una serie de probabilidades pi .4 . En concreto estos valores tienen la
forma
i−α
pi = , (24.10)
n − 2α + 1
5
donde i = 1, . . . , n. Dos son los valores de α que suelen utilizarse
α = 0.375, (24.11)
o bien
α = 0.5. (24.12)
Una vez hemos elegido estos valores pi hemos de determinar los valo-
res de la abscisa y la ordenada del i-ésimo punto. Si xi con i = 1, . . . , n
son los datos entonces los ordenamos obteniendo los estadísticos or-
denados x(i) que verifican
x(1) ≤ . . . ≤ x(n) .
qqnorm(x)
en o en [Thode2002]
5 La función pppoints nos indica los valores que realmente se utilizan.
24.4. CONTRASTE DE NORMALIDAD 391
(a) (b)
(c) (d)
Figura 24.4: (a) Dibujo q-q o cuantil-cuantil para datos x. (b) Dibujo q-q o cuantil-cuantil para la muestra x añadiendo
la línea que pasa por el primer y tercer cuartil. Vemos cómo los puntos están muy próximos a la línea. No podemos
rechazar la normalidad de los datos utilizando este dibujo. (c) Dibujo q-q o cuantil-cuantil para datos y. (d) Dibujo
q-q o cuantil-cuantil para la muestra y añadiendo la línea que pasa por el primer y tercer cuartil. Los puntos están
alejados de la línea. Parece razonable rechazar la normalidad de los datos utilizando este gráfico.
392 CAPÍTULO 24. CONTRASTE DE HIPÓTESIS
qqnorm(x)
qqline(x)
¿Están sobre una línea recta los puntos en cada una de las gráficas?
Podemos ver que para la figura 24.4(b) correspondiente a la muestra
x los datos parecen bien alineados. Esto no parece tan cierto para los
datos de la muestra y que aparecen en la figura 24.4(d). Rechazaría-
mos gráficamente la normalidad de la muestra y mientras que no la
rechazaríamos para la muestra x.
En http://en.wikipedia.org/wiki/Q-Q_plot se tiene una explica-
ción muy completa de este gráfico.
shapiro.test(x)
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.98668, p-value = 0.2204
24.5. CONSTRASTES DE NORMALIDAD 393
shapiro.test(y)
##
## Shapiro-Wilk normality test
##
## data: y
## W = 0.79992, p-value = 1.516e-11
library(nortest)
pearson.test(x)
##
## Pearson chi-square normality test
##
## data: x
## P = 18.239, p-value = 0.1086
Y después a la muestra y.
pearson.test(y)
##
## Pearson chi-square normality test
##
## data: y
## P = 97.099, p-value = 6.69e-16
lillie.test(x)
##
## Lilliefors (Kolmogorov-Smirnov) normality
## test
##
## data: x
## D = 0.060824, p-value = 0.2606
394 CAPÍTULO 24. CONTRASTE DE HIPÓTESIS
lillie.test(y)
##
## Lilliefors (Kolmogorov-Smirnov) normality
## test
##
## data: y
## D = 0.18224, p-value = 1.273e-10
Comparación de dos
poblaciones
25.1 Introducción
Distintos problemas relativos a comparar dos poblaciones se tratan
en este tema. Empezamos abordando el problema de la comparación
mediante herramientas puramente descriptivas de las dos muestras de
que disponemos, una por población en estudio. Seguimos con la com-
paración de dos poblaciones normales, en particular, la comparación
de sus medias y varianzas. Continuamos con la comparación mediante
el test de Kolmogorov-Smirnov para dos muestras. Terminamos con
un test de Montecarlo para comparar las medias de dos poblaciones.
## [1] 23.3 23.4 26.5 25.8 19.1 22.1 26.3 21.9 21.8
## [10] 22.5 19.5 23.1 22.5 26.9 22.4 27.3 24.1 27.8
## [19] 25.1 22.7 24.7 24.6 16.4 23.2 24.8 27.9 19.2
## [28] 26.4 22.3 23.8 19.7 27.6 22.6 20.3 22.3 21.4
## [37] 25.2 19.1 22.5 23.4 20.7 21.6 21.1 24.4 22.1
round(y,1)
## [1] 29.2 28.3 27.9 28.0 30.5 26.0 32.5 28.4 29.0
## [10] 31.8 24.7 22.8 26.5 28.8 23.8 29.9 28.8 31.4
395
396 CAPÍTULO 25. COMPARACIÓN DE DOS POBLACIONES
## [19] 30.9 32.0 31.0 33.4 29.0 23.7 33.8 26.6 31.9
## [28] 30.7 27.3 28.2 36.6 29.8 25.3 31.2 29.6 30.1
## [37] 32.8 28.0 27.9 33.3 26.6 29.3 27.8 30.3 26.3
## [46] 28.5 29.1 29.0 32.9 27.1 32.7 33.4 25.7 28.8
mean(x)
## [1] 23.14726
sd(x)
## [1] 2.630329
y para la segunda
mean(y)
## [1] 29.24535
sd(y)
## [1] 2.850981
(a) (b)
(c) (d)
Figura 25.1: Datos x: histograma (a) y estimador kernel de la densidad de x (b). Datos y: histograma (c) y estimador
kernel de la densidad de x (d).
398 CAPÍTULO 25. COMPARACIÓN DE DOS POBLACIONES
z = data.frame(u = c(x,y),v=factor(rep(c(1,2),c(length(x),length(y))),
levels=1:2,labels=c("x","y")))
png(paste0(dirTamiFigures,"CompDosPob7.png"))
ggplot(z,aes(x=u,group=v,colour=v))+geom_density()
dev.off()
## pdf
## 2
Figura 25.3: Densidades normales: (a) distinta media y la misma varianza; (b) misma media y distinta varianza; (c)
distintas medias y varianzas.
t.test(x)$conf.int
y para la segunda
t.test(y)$conf.int
t.test(x,y,var.equal=TRUE)$conf.int
t.test(x,y,var.equal=FALSE)$conf.int
Si asumimos que las dos varianzas son iguales, esto es, asumimos la
2
hipótesis de que σX = σY2 , denotaremos por σ 2 el valor común: σ 2 =
σX = σY . El valor común σ 2 de la varianza se puede estimar con
2 2
(n − 1)SX
2
+ (m − 1)SY2
Sp2 = .
n+m−2
√
De hecho, lo que tenemos es que SE(X̄n − Ȳm ) = Sp 1
n + 1
m y
X̄ − Ȳ − (µX − µY )
T = √ ∼ tn+m−2 , (25.3)
Sp n1 + m 1
Sp
X̄n − Ȳm ± tn+m−2,1−α/2 .
n+m−2
t.test(x,y,var.equal=TRUE,conf.level=0.95)$conf.int
t.test(x,y,var.equal=TRUE,conf.level=0.99)$conf.int
con ( )
2
SX Sy2
n + m
ν0 = 2 /n)2
(SX 2 /m)2
(SY
.
n−1 + m−1
Ejemplo 25.4 Con los datos que estamos analizando los intervalos
para la diferencia de medias con niveles de confianza 0.95 y 0.99 son
t.test(x,y,var.equal=FALSE,conf.level=0.95)$conf.int
t.test(x,y,var.equal=FALSE,conf.level=0.99)$conf.int
H0 : µX = µY ,
H1 : µX ̸= µY .
t.test(x,y,var.equal=TRUE)
##
## Two Sample t-test
##
## data: x and y
## t = -10.974, df = 97, p-value < 2.2e-16
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -7.200980 -4.995192
## sample estimates:
## mean of x mean of y
## 23.14726 29.24535
t.test(x,y,var.equal=FALSE)
##
## Welch Two Sample t-test
##
## data: x and y
## t = -11.055, df = 95.965, p-value < 2.2e-16
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -7.193018 -5.003155
## sample estimates:
## mean of x mean of y
## 23.14726 29.24535
H0 : µX ≤ µY ,
H1 : µX > µ Y .
H0 : µX ≥ µY ,
H1 : µX < µ Y .
library(Biobase)
data(gse21942,package="tamidata")
y = exprs(gse21942)[54651,]
x = pData(gse21942)[,"FactorValue..DISEASE.STATE."]
t.test(y~x,var.equal=TRUE)
##
## Two Sample t-test
##
## data: y by x
## t = 6.2573, df = 27, p-value = 1.077e-06
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## 2.675284 5.285788
## sample estimates:
## mean in group healthy
## 8.900083
## mean in group multiple sclerosis
## 4.919546
t.test(y~x,var.equal=TRUE)
25.4. INFERENCIA SOBRE LAS VARIANZAS DE DOS POBLACIONES NORMALES405
##
## Two Sample t-test
##
## data: y by x
## t = 6.2573, df = 27, p-value = 1.077e-06
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## 2.675284 5.285788
## sample estimates:
## mean in group healthy
## 8.900083
## mean in group multiple sclerosis
## 4.919546
n = 45
m = 54
x = rnorm(n,mean=23,sd=2.45)
y = rnorm(m,mean=30,sd=3.45)
1.0
que tiene una distribución F (de Fisher) con n − 1 y m − 1 grados de
libertad.
Los tamaños muestrales de nuestros datos son n=45 y m=54. La
y0
S 2 /σ 2
0.5 función de densidad de SX2 /σX 2 aparece en la figura 25.4.
Y Y
Denotemos por Fp (n − 1, m − 1) el percentil de orden p de la
distribución F (n−1, m−1), es decir, el punto que a su izquierda tiene
0.0
## [1] 1.75846
data(gse21942,package="tamidata")
y = exprs(gse21942)[54651,]
x = pData(gse21942)[,"FactorValue..DISEASE.STATE."]
aggregate(y,by=list(x),FUN=var)
## Group.1 x
## 1 healthy 0.1736921
## 2 multiple sclerosis 5.8991638
var.test(y~x)
##
## F test to compare two variances
##
## data: y by x
## F = 0.029444, num df = 14, denom df = 13,
## p-value = 5.258e-08
## alternative hypothesis: true ratio of variances is not equal to 1
## 95 percent confidence interval:
## 0.009553828 0.088680708
## sample estimates:
## ratio of variances
## 0.02944351
cbind(x[1:10],y[1:10])
## [,1] [,2]
## [1,] 47.65658 38.90872
## [2,] 24.43842 31.14831
## [3,] 37.64699 30.06900
## [4,] 39.42556 18.29267
## [5,] 25.56568 41.57664
## [6,] 30.50563 40.43124
## [7,] 40.20254 50.22449
## [8,] 28.01582 38.39682
## [9,] 33.39100 32.93366
## [10,] 40.88822 35.99563
d = x -y
d[1:10]
t.test(d)
##
25.5. COMPARACIÓN DE MEDIAS CON MUESTRAS APAREADAS409
t.test(x,y,paired=TRUE)
##
## Paired t-test
##
## data: x and y
## t = -5.8304, df = 144, p-value = 3.489e-08
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -5.487038 -2.708603
## sample estimates:
## mean of the differences
## -4.097821
(x = c(265,240,258,295,251,245,287,314,260,279,283,240,238,225,247))
## [1] 265 240 258 295 251 245 287 314 260 279 283
## [12] 240 238 225 247
(y = c(229,231,227,240,238,241,234,256,247,239,246,218,219,226,233))
## [1] 229 231 227 240 238 241 234 256 247 239 246
## [12] 218 219 226 233
t.test(x,y,paired=T)
##
## Paired t-test
##
## data: x and y
410 CAPÍTULO 25. COMPARACIÓN DE DOS POBLACIONES
t.test(x,y,paired=T,alternative = "greater")
##
## Paired t-test
##
## data: x and y
## t = 5.4659, df = 14, p-value = 4.158e-05
## alternative hypothesis: true difference in means is greater than 0
## 95 percent confidence interval:
## 18.20922 Inf
## sample estimates:
## mean of the differences
## 26.86667
una normal.
0.04
N = 45 Bandwidth = 2.911
normal. Finalmente, si aplicamos un test de normalidad a las muestras
(en concreto, vamos a utilizar el test de Shapiro-Wilk) obtenemos los
Figura 25.5: Estimadores kernel siguientes resultados.
de la densidad de x (trazo conti-
nuo) e y (trazo discontinuo). shapiro.test(x)
25.6. TEST DE KOLMOGOROV-SMIRNOV PARA DOS MUESTRAS 411
##
## Shapiro-Wilk normality test
##
## data: x
## W = 0.88088, p-value = 0.0002536
shapiro.test(y)
##
## Shapiro-Wilk normality test
##
## data: y
## W = 0.75051, p-value = 3.23e-08
png(paste0(dirTamiFigures,"CompDosPob44.png"))
qqnorm(x)
qqline(x)
dev.off()
## pdf
## 2
## pdf
## 2
(a) (b)
Figura 25.6: (a) Dibujo q-q de la muestra x. Vemos que los puntos se
alejan de la línea indicando que no hay normalidad en los datos. (b)
Dibujo q-q de la muestra y. Vemos que los puntos se alejan de la línea
indicando que no hay normalidad en los datos.
library(Hmisc)
xy = c(x,y)
xcdf = ecdf(x)
ycdf = ecdf(y)
xy1 = xy[which.max(abs(xcdf(xy) - ycdf(xy)))]
png(paste0(dirTamiFigures,"CompDosPob46.png"))
Ecdf(xy, group= c(rep(1,length(x)),rep(2,length(y))),xlab="z")
segments(xy1,xcdf(xy1),xy1,ycdf(xy1),lty=2)
dev.off()
## pdf
## 2
ks.test(x,y)
##
## Two-sample Kolmogorov-Smirnov test
##
## data: x and y
## D = 0.38519, p-value = 0.000928
## alternative hypothesis: two-sided
Datos categóricos
415
416 CAPÍTULO 26. DATOS CATEGÓRICOS
library(Hmisc,T)
binconf(x=189, n=11034, method="asymptotic")
26.1.1 Ejercicios
Ejercicio 60
Para los datos de la tabla 23.1 se pide:
Ejercicio 61
[152, pág. 120, problema 21] Se observan los siguientes éxitos y
fracasos: 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0. Calcule un intervalo
de confianza con nivel 0,95 para la probabilidad de éxito p.
Ejercicio 62
[152, pág. 120, problema 22] Teniendo en cuenta los siguientes
resultados para una muestra de una distribución binomial, calcule el
error estándar de p̂ cuando:
1. n = 25, X = 5.
2. n = 48, X = 12.
3. n = 100, X = 80.
4. n = 300, X = 160.
Ejercicio 63
[152, pág. 120, problema 23] Entre los 100 adultos seleccionados al
azar, 10 se encontraron desempleados. Dar una intervalo de confianza
con un nivel de 0,99 para el porcentaje de adultos desempleados.
Ejercicio 64
[152, pág. 121, problema 31] Una compañía de cosméticos encontró
que 180 de cada 1000 mujeres seleccionadas al azar en Nueva York han
visto el anuncio de televisión de la empresa. Calcule un intervalo de
confianza al 0,95 para el porcentaje de mujeres en la ciudad de Nueva
York que han visto el anuncio.
26.2.1 Exercises
Ejercicio 65
Pretendemos estimar la proporción de palmeras afectadas por el
picudo. Se ha tomado una primera muestra de 100 palmeras al azar.
Se han observado 23 palmeras afectadas. Se pide:
1. ¿Cuál es el error máximo observado con un nivel de confianza
de 0.95?
2. Tomamos como estimación inicial de p el valor observado con la
primera muestra de 100 palmeras. Supongamos que nos plantea-
mos estimar la proporción de palmeras afectadas con un error
máximo de 0.04 y un nivel de confianza de 0.95. ¿Cuál ha de ser
el número total de palmeras a observar?
3. Responde a la pregunta del apartado 2 suponiendo que deseamos
un nivel de confianza en el error máximo de 0.99. Mantenemos
el error máximo en 0.04.
4. Responde a la pregunta del apartado 2 suponiendo que deseamos
un nivel de confianza en el error máximo de 0.95 pero queremos
un error máximo de 0.02.
5. ¿Más nivel de confianza supone más muestra? Responde la pre-
gunta considerando los apartados anteriores.
26.3. VARIAS VARIABLES CATEGÓRICAS 419
πij = P (X = i, Y = j),
∑
I ∑
I
π·j = P (Y = j) = P (X = i, Y = j) = πij
i=1 i=1
P (X = i, Y = j) = P (X = i)P (Y = j)
esto es
πij = πi· π·j .
En particular, la condicionada es igual a la marginal.
uno de dos posibles grupos: toma una aspirina diaria (grupo aspiri-
na) o bien le damos diariamente un placebo (grupo placebo). Se toma
una gran muestra y los resultados los tenemos en la tabla 26.2 don-
de el número que aparece en cada celda de la tabla indica el número
de veces que se da simultáneamente el valor correspondiente de la fi-
la y columna consideradas. Esta tabla recibe el nombre de tabla de
contingencia1 o tabla de clasificación cruzada. De un modo genérico
podemos considerar la tabla 26.3 donde denotamos por nij el número
de ocurrencias del valor i de X y del valor j de Y . Por ni· denotamos
la suma de los conteos de la fila, esto es, del total de veces que X toma
el valor i. Análogamente por n·j denotamos el total de la columna j y
nos da el número total de veces que la variable Y ha tomado el valor
j. Notemos que estimamos la distribución conjunta (ver tabla 26.4)
con
nij
P̂ (X = i, Y = j) = π̂ij = (26.1)
n
La distribución condicionada de la variable Y a la variable X (tabla
26.5) la estimaríamos con
nij
P̂ (Y = j|X = i) = π̂j|i = . (26.2)
ni·
De un modo similar podemos estimar la distribución condicionada de
la variable X a la variable Y .
nij
P̂ (X = i|Y = j) = π̂i|j = . (26.3)
n·j
P (Y = 1|X = i) = πi , (26.4)
P (Y = 2|X = i) = 1 − πi . (26.5)
P (A)
.
1 − P (A)
de Estadística.
3 Tenemos que
m− ≤ n11 ≤ m·
H1 : θ > 1
Modelos lineales
library(Biobase)
data(gse44456,package="tamidata")
featureNames(gse44456)[19254]
## [1] "8047097"
## pdf
## 2
425
426 CAPÍTULO 27. MODELOS LINEALES
Figura 27.2: a) Datos. b) Los datos con dos líneas: la línea horizontal
que corta al eje de ordenadas en ȳ y la línea vertical que corta al
eje de abscisas en x̄. c) Los datos, la línea horizontal que corta al eje
de ordenadas en ȳ y la línea vertical que corta al eje de abscisas en
x̄. Representamos en rojo aquellos puntos donde el producto cruzado
(xi − x̄)(yi − ȳ) es positivo y en azul aquellos puntos donde el producto
toma un valor negativo.
cor(x1,y1)
## [1] 0.7769814
(a) (b)
(c) (d)
Figura 27.3: Ejemplo con fuerte asociación lineal: datos (a) y los datos diferenciando el signo del producto cruzado.
Las figuras (c) y (d) son los dibujos análogos con datos en los que apenas hay asociación lineal entre las abscisas y
las ordenadas.
cor(x2,y2)
## [1] 0.9889923
cor(x3,y3)
## [1] 0.08869201
cov(M)
cov(t(M))
cor(M)
cor(t(M))
Y = β0 + β1 x + ϵ, (27.5)
donde
ϵ ∼ N (0, σ 2 ). (27.6)
En la formulación de 27.5 expresamos el valor aleatorio de Y como
suma de una parte que sistemáticamente depende de x (la compo-
nente sistemática del modelo) y un término aleatorio con distribución
normal, un término de error o desajuste del modelo. En esta variable
normal con media cero y varianza constante σ 2 estamos incluyendo
todas las posibles causas que influyen el valor de Y y que no vienen
dadas por la variable predictora.
No consideramos un solo valor aleatorio de Y dado un valor fijo
de x. Realmente, tenemos n valores observados cuyos valores son in-
dependientes entre sí pero no tienen la misma distribución. Hemos de
pensar que cad a Yi tiene una variable predictora distinta que influye
en la distribución de Yi . Tenemos pares (xi , Yi ) donde la xi viene da-
da y consideramos la distribución de Yi condicionada a xi , es decir,
Yi | xi .
Resumiendo, estamos asumiendo que Yi ∼ N (β0 + β1 xi , σ 2 ) y que
los distintos Yi son independientes entre si. Utilizando propiedades de
la distribución normal multivariante tenemos que estas hipótesis las
podemos expresar conjuntamente diciendo que
Y ∼ Nn (Xβ, σ 2 In×n ), (27.7)
donde
Y1 1 x1 [ ]
.. .. β
Y = ... X = . . β= 0
β1
Yn 1 xn
Si consideramos que
ϵ1
..
ϵ=.
ϵn
donde los ϵi ∼ N (0, σ 2 ) e independientes entre si. Entonces el modelo
dado en 27.7 lo podemos reescribir como
Y = Xβ + ϵ, (27.8)
con ϵ ∼ Nn (0, σ 2 In×n ).
Este modelo probabilístico es conocido como el modelo de re-
gresión lineal simple. No lo estudiaremos en más detalle porque
nos vamos a ocupar de la situación más general en que tenemos más
de una variable predictora. No es más que un caso particular y sin
mucha dificultad adicional se puede estudiar el situación general de
regresión lineal múltiple.
432 CAPÍTULO 27. MODELOS LINEALES
Y = f (x1 , . . . , xn ) + ϵ, (27.9)
Y = Xβ + ϵ. (27.10)
X ′ X β̂ = X ′ y. (27.12)
27.5. ESTIMACIÓN DE β 433
1 x1 − x̄
.. ..
X = . .
1 xn − x̄
con
[ ]
′ n ∑ 0
XX= n
i=1 (xi − x̄)
2
0
27.7 Verosimilitud
Dados los datos (xi , yi ) con i = 1, . . . , n la verosimilitud de y =
(y1 , . . . , yn )′ vendría dada por
1 1
L(β, σ) = n
n
exp{− 2 (y − Xβ)′ (y − Xβ)} (27.25)
(2π) σ
2 2σ
y la logverosimilitud sería
n 1
l(β, σ) = log(2π) − n log σ − 2 (y − Xβ)′ (y − Xβ). (27.26)
2 2σ
El estimador máximo verosímil de β se obtiene maximizando cualquie-
ra de las dos funciones anteriores. Es obvio que el máximo respecto
de β se obtiene como el valor que minimiza (y − Xβ)′ (y − Xβ), en
definitiva, que los estimadores máximo verosímiles no son más que los
estimadores mínimo cuadráticos.
ϵ̂′ ϵ̂
σ̂ 2 = . (27.30)
n−p
Ya podemos estimar var(β̂). Este estimador sería
ar(β̂) = (X ′ X)−1 σ̂ 2 .
vd (27.31)
∑n
Es habitual denominar a i=1 (yi − ŷi )2 , ∑
suma de cuadrados del
n
i=1 (ŷi − ȳ) se le llama
2
error mientras que a SS(Regresion) =
suma de cuadrados de la regresión. Tenemos pues que
∑n
(ŷi − ȳ)2 SS(Regresion)
R = ∑ni=1
2
= . (27.35)
(y
i=1 i − ȳi )2 SS(T otal)
El ajuste que estamos realizando se supone que será tanto mejor cuan-
to más pequeña sea SS(Error). Tampoco sería natural que SS(Error)
fuera nula pues sería tanto como asumir que los distintos valores alea-
torios son iguales a su media. Notemos que SS(T otal) es una cuan-
tificación de la variabilidad de los distintos yi sin tener en cuenta las
variables predictoras mientras que SS(Error) nos cuantifica la varia-
ción residual después de utilizar las variables predictoras. Es de espe-
rar que un mejor ajuste vaya acompañado de un valor de SS(Error)
pequeño en relación con SS(T otal). Esa es la idea del coeficiente de
determinación. Toma valores entre 0 y 1 y cuanto más cerca de 1
mejor es el ajuste.
Tiene un pequeño inconveniente y es que no tiene en cuenta el nú-
mero de variables predictoras que estamos utilizando para predecir la
variable respuesta. Una pequeña modificación de R2 para incorporar
esta información es el coeficiente de determinación ajustado que
podemos denotar R2 -ajustado y se define como
∑n
(yi − ŷi )2 /(n − p)
R2 − ajustado = 1 − ∑i=1 n , (27.36)
i=1 (yi − ȳ) /(n − 1)
2
y = exprs(gse44456)[19254,]
x = pData(gse44456)[,"pH"]
gse44456_19254 = data.frame(y,x)
## pdf
## 2
## pdf
## 2
## pdf
## 2
√ √ √
En la figura 27.8 los valores por los que multiplicamos son 1, 2, 3, . . . , 50
por lo que las varianzas se incrementan mucho menos de una abscisa
a la siguiente.
## pdf
## 2
## pdf
## 2
27.10.2 Normalidad
La siguiente hipótesis a valorar es la normalidad de los errores. La
herramienta gráfica más habitual es el dibujo q-q o la representación
cuantil-cuantil. Ordenamos los residuos y representamos los residuos
ordenados en función de Φ−1 ( n+1 i
) para i = 1, . . . , n. Si los residuos
tienen una distribución normal entonces deben estar alineados. El
histograma no es muy adecuado para ver la normalidad de los residuos.
## pdf
## 2
Hemos visto cómo es una dibujo q-q cuando tenemos normalidad. Pe-
ro: ¿y qué pasa cuando no tenemos normalidad. Esto es lo interesante
saber qué tenemos que buscar para detectar que los residuos no siguen
una distribución normal.
## pdf
## 2
## pdf
## 2
La figura 27.14 que sigue muestra el dibujo q-q con datos simulados
correspondientes a la distribución lognormal.
442 CAPÍTULO 27. MODELOS LINEALES
## pdf
## 2
La figura 27.15 que sigue muestra el dibujo q-q con datos simulados
correspondientes a la distribución de Cauchy.
## pdf
## 2
La figura 27.16 que sigue muestra el dibujo q-q con datos simulados
correspondientes a la distribución de uniforme.
## pdf
## 2
library(lmtest)
dwtest(gen19254.lm)
##
## Durbin-Watson test
##
## data: gen19254.lm
## DW = 2.3323, p-value = 0.8575
## alternative hypothesis: true autocorrelation is greater than 0
gen19254.inf = influence(gen19254.lm)
head(gen19254.inf$hat)
## GSM1085665_HE32H001.CEL
## 0.02890237
## GSM1085666_HE32H003.CEL
## 0.31508019
## GSM1085667_HE32H004.CEL
## 0.03777124
## GSM1085668_HE32H005.CEL
## 0.02890237
## GSM1085669_HE32H006_2_.CEL
## 0.02611433
## GSM1085670_HE32H007_2_.CEL
## 0.02769529
Y las representamos en la figura 27.17.
## pdf
## 2
Puesto que cada uno de los ti sigue una distribución conocida pode-
mos contrastar si tenemos una observación anómala. En principio el
procedimiento sería simplemente fijar un nivel de significación α y de-
terminar el percentil 1− α2 de una distribución t de Student con n−p−1
grados de libertad. Si denotamos el percentil como tn−p−1,1− α2 enton-
ces residuos que no estén en el intervalo [−tn−p−1,1− α2 , tn−p−1,1− α2 ]
serían sospechosos. Esto no es adecuado. Porque estamos analizan-
do n residuos estudentizados. Con uno sólo sí que sería aplicable el
razonamiento. Tenemos un problema de muchos tests simultáneamen-
te considerados. Si aplicamos la corrección de Bonferroni tendríamos
que corregir el nivel de significación α y trabajar con α/n. Por tanto,
consideramos como sospechosos aquellos residuos estandarizados que
estén fuera del intervalo [−tn−p−1,1− 2nα ,t α ].
n−p−1,1− 2n
gen19254.rs = rstudent(gen19254.lm)
##
## FALSE
## 39
png(paste0(dirTamiFigures,"ModLin49.png"))
plot(gen19254.lm, which = 4)
dev.off()
## pdf
## 2
head(cooks.distance(gen19254.lm))
## GSM1085665_HE32H001.CEL
## 0.0095804543
## GSM1085666_HE32H003.CEL
## 0.0005716436
## GSM1085667_HE32H004.CEL
## 0.0007746346
## GSM1085668_HE32H005.CEL
## 0.0071691187
## GSM1085669_HE32H006_2_.CEL
## 0.0630919910
## GSM1085670_HE32H007_2_.CEL
## 0.0461454249
max(β,σ)∈Ω0 L(β, σ)
Λ= (27.42)
max(β,σ)∈Ω L(β, σ)
siendo L(β, σ) = 1
n exp{− 2σ1 2 (y−Xβ)′ (y−Xβ)}, Ω0 = {(β, σ) ∈
(2π) 2 σ n
Rp × (0, +∞) : βi1 = . . . = βir = 0} y Ω = Rp × (0, +∞). Como es
habitual en un test del cociente de verosimilitudes rechazaríamos la
hipótesis nula si Λ es pequeño (menor que una cierta constante) que
se prueba es equivalente a que
SS(Error)Ω0 − SS(Error)Ω
SS(Error)Ω
sea grande (mayor que una cierta constante). Denotamos por SS(Error)Ω0
la suma de cuadrados del error bajo la hipótesis nula y SS(Error)Ω
la suma de cuadrados sobre todo el espacio paramétrico. Bajo la hi-
pótesis nula se verifica que
SS(Error)Ω0 − SS(Error)Ω
∼ χ2r
σ2 r
27.11. INFERENCIA SOBRE EL MODELO 449
y
SS(Error)Ω
∼ χ2n−p
σ 2 (n − p)
además ambas cantidades son independientes. Por ello se verifica que
F = t2i .
o bien si
F = t2i > F1,n−p,1− α2 .
Ambos procedimientos son equivalentes como se puede ver fácilmente.
summary(gen19254.lm)
##
## Call:
## lm(formula = y ~ x, data = gse44456_19254)
##
## Residuals:
## Min 1Q Median 3Q Max
450 CAPÍTULO 27. MODELOS LINEALES
confint(gen19254.lm)
## 2.5 % 97.5 %
## (Intercept) -6.416593 -0.2121019
## x 1.431029 2.3857477
x′0 β̂,
x′0 β̂
var(x′0 β̂) + σ 2
head(predict(gen19254.lm))
## GSM1085665_HE32H001.CEL
## 9.261931
## GSM1085666_HE32H003.CEL
## 7.334459
## GSM1085667_HE32H004.CEL
## 9.433686
## GSM1085668_HE32H005.CEL
## 9.261931
## GSM1085669_HE32H006_2_.CEL
## 9.147428
## GSM1085670_HE32H007_2_.CEL
## 9.223763
## fit lwr
## GSM1085665_HE32H001.CEL 9.261931 9.124197
## GSM1085666_HE32H003.CEL 7.334459 6.879696
## GSM1085667_HE32H004.CEL 9.433686 9.276231
452 CAPÍTULO 27. MODELOS LINEALES
## fit lwr
## GSM1085665_HE32H001.CEL 9.261931 8.440140
## GSM1085666_HE32H003.CEL 7.334459 6.405385
## GSM1085667_HE32H004.CEL 9.433686 8.608361
## GSM1085668_HE32H005.CEL 9.261931 8.440140
## GSM1085669_HE32H006_2_.CEL 9.147428 8.326751
## GSM1085670_HE32H007_2_.CEL 9.223763 8.402454
## upr
## GSM1085665_HE32H001.CEL 10.083722
## GSM1085666_HE32H003.CEL 8.263533
## GSM1085667_HE32H004.CEL 10.259011
## GSM1085668_HE32H005.CEL 10.083722
## GSM1085669_HE32H006_2_.CEL 9.968104
## GSM1085670_HE32H007_2_.CEL 10.045072
library(MASS)
stepAIC(gen19254.lm)
## Start: AIC=-69.55
## y ~ x
##
## Df Sum of Sq RSS AIC
## <none> 5.9155 -69.554
## - x 1 10.49 16.4058 -31.771
##
## Call:
## lm(formula = y ~ x, data = gse44456_19254)
##
## Coefficients:
454 CAPÍTULO 27. MODELOS LINEALES
## (Intercept) x
## -3.314 1.908
Conceptos
fundamentales de
Estadística
28.1 Verosimilitud
Sea y = (y1 , . . . , yn ) una realización del vector aleatorio Y =
(Y1 , . . . , Yn ). Es habitual asumir que Y tiene una función de densi-
dad conjunta f en una cierta familia F. Para una función dada f ,
el valor f (y) nos muestra cómo varía la densidad dentro del espacio
muestral de valores posibles de y. Y viceversa, si consideramos unos
datos y y lo que hacemos variar es la función de densidad entonces
estamos viendo cómo de verosímil es cada una de las funciones dados
los datos y. Esta función recibe el nombre de verosimilitud de f
dados los datos y y se suele denotar como
V erosimilitud[f ; y] = L(f ; y) = f (y). (28.1)
Con frecuencia, es conveniente trabajar con el logaritmo natural de la
función anterior y hablaremos de la log-verosimilitud.
l[f ; y] = log f (y). (28.2)
Una simplificación adicional (que es habitual en las aplicaciones) su-
pone que la función de densidad f pertenece a una familia paramétri-
ca F, esto es, cada elemento de la familia es conocido completamente
salvo un número finito de parámetros θ = (θ1 , . . . , θp ) de modo que
denotaremos f (y; θ) o fY (y; θ). Al conjunto de valores posibles de θ
se le llama espacio paramétrico y lo denotaremos por Θ. En este
caso, la logverosimilitud es una función de θ y denotaremos
V erosimilitud[θ; y] = l(θ; y) = log f (y; θ). (28.3)
455
456CAPÍTULO 28. CONCEPTOS FUNDAMENTALES DE ESTADÍSTICA
y
∑
n ∑
n
ly (θ; y) = log fYi (yi ) = LYi (θ; yi ).
i=1 i=1
28.2 Estimación
Denotamos por Θ el espacio formado por los valores que puede
tomar θ o espacio paramétrico. Un estimador del parámetros o vector
paramétrico θ es cualquier función de la muestra X1 , . . . , Xn que toma
valores en el espacio paramétrico. Si δ(X1 , . . . , Xn ) es un estimador
del parámetro θ entonces se define el error cuadrático medio como
Notemos que
1∑ 1∑ 1∑
n n n
E Ȳ = E[ Yi ] = EYi = µ = µ.
n i=1 n i=1 n i=1
1 ∑
n
S2 = (Yi − Ȳ )2 . (28.7)
n − 1 i=1
∑
n
σ2
E (Yi − Ȳ )2 = nσ 2 − = nσ 2 − σ 2 = (n − 1)σ 2 ,
i=1
n
de donde,
1 ∑
n
ES 2 = E (Yi − Ȳ )2 = σ 2 ,
n − 1 i=1
es decir, S 2 estima la varianza σ 2 sin sesgo.
1 ∑
n
Sjk = (Yij − Ȳ·j )(Yik − Ȳ·k ),
n − 1 i=1
de modo que
S11 ... S1d
1 ∑
n
.. .. .. = 1
S= . . . (Yi − Ȳ )(Yi − Ȳ )′ = Q.
n − 1 i=1 n−1
Sd1 ... Sdd
o también
θ̂ = argmaxθ∈Θ L(θ), (28.12)
Ejemplo
∑n 28.4 (Bernoulli) Se puede comprobar sin dificultad que
i=1 xi
p̂ = n .
460CAPÍTULO 28. CONCEPTOS FUNDAMENTALES DE ESTADÍSTICA
Notemos que el error estándar de θ̂j será el elemento que ocupa la po-
sición (j, j) en la inversa de la matriz de información. Cuanto mayor
es la curvatura de la logverosimilitud menores serán los errores están-
dar. La racionalidad que hay detrás de esto es que si la curvatura es
mayor entonces la logverosimilitud cae rápidamente cuando el vector
θ se aleja de θ̂. En resumen, es de esperar que θ esté más próximo a
θ̂.
Ejemplo 28.6 (Binomial) Supongamos que una muestra en una po-
blación finita y consideremos como valor observado el número de éxi-
tos. Entonces la verosimilitud sería
( )
n y
L(p) = p (1 − p)n−y , (28.15)
y
H0 H1
Rechazamos H0 Error tipo I
No rechazamos H0 Error tipo II
H0 :θ ∈ Θ0 (28.19)
H1 :θ ∈ Θ1 (28.20)
H0 :µ = µ0 , (28.22)
H1 :µ ̸= µ0 . (28.23)
∑n
i=1 (Xi −X̄)
2
Siendo S 2 = n−1 , el estadístico habitualmente utilizado es el
siguiente
X̄ − µ0
T = √ .
S/ n
Bajo la hipótesis nula este estadístico sigue una distribución t de Stu-
dent con n − 1 grados de libertad,
T ∼ t(n − 1).
462CAPÍTULO 28. CONCEPTOS FUNDAMENTALES DE ESTADÍSTICA
|T | > tn−1,1− α2 .
H0 :θ = θ0 , (28.26)
H1 :θ ̸= θ0 . (28.27)
θ̂ − θ0
z= (28.28)
SE(θ̂)
Modelos lineales
generalizados
ηi = x′i β
ηi = g(µi )
O lo que es lo mismo ∑
g(µi ) = βj xij
j
para i = 1, . . . , n.
En el siguiente ejemplo consideramos el caso de respuesta binaria.
Ejemplo 29.1 (Modelos logit binomiales para datos binarios)
Tenemos respuesta binaria (éxito como 1 y fracaso como 0), esto es,
Y ∼ Bi(1, π).
f (y|π) = π y (1 − π)1−y =
( )
π
(1 − π)[π/(1 − π)]y = (1 − π) exp y log
1−π
Y ∼ P o(µ)
29.2. DESVIACIÓN 467
Q(µ) = log(µ),
29.2 Desviación
Los valores observados son y = (y1 , . . . , yn ) y el vector de me-
dias µ = (µ1 , . . . , µn ) Sea L(µ; y) la logverosimilitud expresada como
función de las medias. Sea L(µ̂; y) el máximo de la logverosimilitud
asumiendo el modelo. Si utilizamos un parámetro distinto para cada
observación. Esto nos proporciona un ajuste perfecto con
µ̂ = y.
β = link[π(1)] − link[π(0)]
β = π(1) − π(0)
468 CAPÍTULO 29. MODELOS LINEALES GENERALIZADOS
• θi es el parámetro natural.
• Si ϕ es conocido entonces la densidad anterior es de la familia
exponencial natural.
Normal Poisson Binomial
2 (n ) µ
f (y) √1
2πσ
exp(− (y−µ)
2σ 2 ) µy e−µ /y! y ( n )(1 − n )
µ n−y
µi = E(Yi ) = b′ (θi ).
y
var(Yi ) = b′′ (θi )a(ϕ).
La componente sistemática viene dada por
∑
ηi = βj xij , i = 1, . . . , n.
j
470 CAPÍTULO 29. MODELOS LINEALES GENERALIZADOS
y en forma matricial
η = Xβ
con η = (η1 , . . . , ηp )′ y β = (β1 , . . . , βp )′ siendo X la matriz de
modelo.
• El parámetro natural θi es
∑
θi = g(µi ) = βj xij
j
La logverosimilitud sería
∑ ∑ ∑ yi θi − b(θi ) ∑
L(β) = Li = log f (yi ; θi , ϕ) = + c(yi , ϕ).
i i i
a(ϕ) i
∂ 2 L(β) ∑n
∂ 2 Li (β)
Ihj = −E =− E =
∂βh ∂βj i=1
∂βh ∂βj
∑ ( )2
∂Li (β) ∂Li (β) ∑ xih xij ∂µi
n n
E =
i=1
∂βh ∂βj i=1
var(Yi ) ∂ηi
I = X ′W X
siendo
W = diag(w1 , . . . , wp )
con ( )2
1 ∂µi
wi =
var(Yi ) ∂ηi
• Estimamos W en β̂ y tendremos
Î = X ′ Ŵ X
siendo
c β̂) = (X ′ Ŵ X)−1
cov(
29.6. INFERENCIA PARA MODELOS LINEALES GENERALIZADOS471
log µ = Xβ
ηi = log µi
de donde
∂µi
= exp ηi = µi
∂ηi
• Además
varYi = µi
∑
• Estamos igualando∑ los estadísticos suficientes i yi xij a sus
valores esperados i µi xij
• Además ( )2
1 ∂µi
wi = = µi
var(Yi ) ∂ηi
Si asumimos que
ϕ
a(ϕ) =
ωi
entonces
• La desviación es igual a
∑
D(y, µ̂) = 2 [yi log(yi /µ̂i ) − yi + µ̂i ].
i
• Tenemos
θ̂i = log[π̂i /(1 − π̂i )]
1
a(ϕ) =
ni
ϕ = 1, ωi = ni .
• Se tiene
• El residuo de Pearson es
yi − µ̂i
ei =
vd
ar(Yi )1/2
• Pero
cov(Y − µ̂) = cov(Y )(I − H)
con
H = W 2 X(X ′ W X)−1 X ′ W 2
1 1
• notaR/notaR025.pdf.
474 CAPÍTULO 29. MODELOS LINEALES GENERALIZADOS
∂L(β)
u=
∂β
y la matriz hessiana
[ ]
∂ 2 L(β)
H=
∂βa ∂βb a,b=1,...,p
29.6.5 IRLS
En esta sección vamos a ver el procedimiento que se utiliza para el
267
Iteratively Reweighted ajuste de los modelos lineales generalizados conocido como IRLS267
Least Square, esto es, míni- Vamos a suponer que la componente aleatoria del modelo o distri-
mos cuadrados iterativamen- bución de la variable respuesta sigue una distribución en la familia de
te reponderados. dispersión exponencial.
o bien
I(t) β (t+1) = I(t) β (t) + u(t)
z = Xβ + ϵ
(X ′ V −1 X)−1 X ′ V −1 z
• Se ve fácilmente que
con
(t)
∑ (t) (t)
(t)
∂ηi
zi = xij βj + (yi − µi ) (t)
=
j ∂µi
(t)
(t) (t) ∂ηi
ηi + (yi − µi ) (t)
∂µi
∂ηi
g(yi ) ≈ g(µi ) + (yi − µi )g ′ (µi ) = ηi + (yi − µi ) = zi
∂µi
(X ′ Ŵ X)−1
con ( )2
∂µi 1
wi =
∂ηi var(Yi )
v(µi ) = ϕµi ,
Meta-análisis
∑
k
X 2 = −2 ln Pi . (30.1)
i=1
477
478 CAPÍTULO 30. META-ANÁLISIS
siendo Zi = Φ−1 (1 − Pi ).
Notemos que el método de Fisher suma los valores −2 ln(pi ). Por
otro lado el Z-valor de Stouffer lo que propone es (por una constante)
una suma de Zi valores. En ambos casos sumamos la contribución de
cada test que√ en un caso lo cuantificamos con −2 ln(pi ) y en otro con
Φ−1 (1 − pi )/ k. En la figura ?? comparamos los sumandos con el
siguiente código.
2
1
p = seq(.01,.99,.001)
plot(-log(p),qnorm(1-p),type="l",xlab = expression(-ln(p)),
0
z
ylab = "z")
−1
−2
0 1 2 3 4
− ln(p)
Miscelánea
4. Consideramos1
xi − m x
ui = ,
cmd + ϵ
con i = 1, . . . , n. Los valores por defecto son c = 5 y e = 0.0001
(con el valor de e evitamos la división por cero).
479
480 CAPÍTULO 31. MISCELÁNEA
x = c(12,3,45,21,34,35,21,456)
library(affy)
tukey.biweight(x, c = 5, epsilon = 1e-04)
## [1] 25.1902
yij = m + ai + bj + eij
y = matrix(c(18,11,8,21,4,13,7,5,16,7,15,6,7,16,6,19,15,12,18,5),
ncol=5)
rownames(y) = paste("chip",1:4)
colnames(y) = paste("sonda",1:5)
medpolish(y)
## 1: 82
## Final: 82
##
## Median Polish Results (Dataset: "y")
##
## Overall: 10.5
##
## Row Effects:
## chip 1 chip 2 chip 3 chip 4
## 5 2 -2 -4
##
## Column Effects:
## sonda 1 sonda 2 sonda 3 sonda 4 sonda 5
## 1.0 -1.5 0.0 0.5 -0.5
##
## Residuals:
## sonda 1 sonda 2 sonda 3 sonda 4 sonda 5
## chip 1 1.5 -10 0.5 -9 0
## chip 2 -2.5 2 -5.5 3 0
## chip 3 -1.5 0 6.5 -3 10
## chip 4 13.5 0 -0.5 12 -1
482 CAPÍTULO 31. MISCELÁNEA
Investigación
reproducible
485
Capítulo 32
Investigacion
reproducible
32.1 Markdown
Es un lenguaje de marcas ligero (minimal sería más correcto). Pre-
tende ser una forma rápida de escribir HTML. Segun su autor, John
Gruber, “HTML is a publishing format; Markdown is a writing for-
mat.”
La dirección indicada contiene una muy buena exposición de este
lenguaje de marcas.
De las distintas versiones del lenguaje Markdown la más intere-
sante para nosotros es la asociada a pandoc, Pandoc’s Markdown.
32.2 RMarkdown
El paquete [6, rmarkdown] incorpora una implementación del len-
guaje de marcas Markdown y utilizado conjuntamente con [160, knitr]
permite generar unos muy buenos informes. La página http://rmarkdown.
rstudio.com/ es el mejor lugar para aprender a manejarlo.
1. En /home/gag/emacs.d/1 ejecutamos
491
492CAPÍTULO 33. LO QUE NO SE DEBE HACER PERO SE HACE
misma variable.
¿Y con RNA-seq? La cosa no es tan simple de evaluar. Es claro
que el tema de los protocolos han de ser los mismos. Y luego hay
que utilizar los mismos alineadores y con los mismos parámetros. Hay
que considerar los posibles errores sistemáticos producidos por los
procedimientos de alineamiento. En este sentido si se utilizan datos
procesados disponibles en la red no parece razonable combinar esta
información. Se debe de utilizar el mismo material base, con lecturas
de la misma longitud, conseguidas con el mismo producto.
Una práctica (que espero no se transforme en habitual) consiste
en construir bancos de datos reunión datos de distintos experimentos.
Esta confusión hace que a veces se toman distintos experimentos.
De cada uno de estos experimentos se observa una variable distinta
asociada a un mismo gen. Y se construye una matriz de datos donde
en filas tenemos genes y en columnas tenemos variables medidas en
distintos experimentos. Las variables que observamos en distintas ex-
perimentaciones aunque se refieran a un mismo gen son observaciones
independientes que además no están observadas en las mismas condi-
ciones experimentales. Por lo tanto no podemos estudiar la dependen-
cia que pueda existir entre ellas. Insisto, son valores independientes
de distribuciones distintas y la posible dependencia que observemos
será puro ruido. Y se hace.
494CAPÍTULO 33. LO QUE NO SE DEBE HACER PERO SE HACE
Apéndice A
Soluciones ejercicios
2.sum(x == 3)
## [1] 16
3.y = sort(x)
cumsum(y)
## [1] 0 1 3 5 7 9 11 13 15 17 20
## [12] 23 26 29 32 35 38 41 44 47 50 53
## [23] 56 59 62 65 69 73 77 81 85 89 93
## [34] 97 101 105 109 113 117 121 125 129 133 137
## [45] 141 146 151 156 161 166 171 176 181 186 191
## [56] 196 201 206 211 216 221 226 232 238 244 250
## [67] 256 262 268 274 280 286 292 298 304 310 316
## [78] 323 330 337 344 351 358 365 372 379 387 395
## [89] 403 411 419 427 435 443 452 461 470 479 489
## [100] 500
495
496 APÉNDICE A. SOLUCIONES EJERCICIOS
2.sum(x <46)
## [1] 15778
sum(floor(x) == 40)
## [1] 638
2.which.max(apply(x,2,mean))
## [1] 58
3.which.min(apply(x,1,mean))
## [1] 143
4.which.min(apply(x,1,IQR))
## [1] 282
6.rowmean = apply(x,1,mean)
sum(x[,45] >= rowmean)
## [1] 1220
data(golub,package="multtest")
golub.fac = factor(golub.cl,levels=0:1,labels=c("ALL","AML"))
m1 = apply(golub,1,mean)
2.sd1 = apply(golub,1,sd)
2.apply(x,2,max)
3.minrow = apply(x,1,min)
which.min(minrow)
## [1] 78
4.which.max(minrow)
## [1] 50
5.quantile(x[,1],probs=0.34)
## 34%
## 0.3489822
6.meanrow = apply(x,1,mean)
quantile(x[,1],probs=0.34)
## 34%
## 0.3489822
7.min(x)
## [1] 0.0004653491
max(x)
## [1] 0.9994045
mean(x)
## [1] 0.4952837
498 APÉNDICE A. SOLUCIONES EJERCICIOS
8.pacman::p_load(ggplot2)
df= data.frame(x)
ggplot(df,aes(x=X1)) + geom_histogram()
6
count
9.pacman::p_load(ggplot2)
df= data.frame(x)
ggplot(df,aes(x=X1)) + geom_density()
499
0.9
density 0.6
0.3
0.0
10.sum(x>.12)
## [1] 448
12.IQR(x1)
## [1] 1
2.names(df) = paste0("probe",1:ncol(df))
3.type = factor(golub.cl,levels=0:1,labels=c("ALL","AML"))
df= data.frame(df,type)
Solución (Ej. 11) — Los dos primeros paquetes [71, ggfortify] y [46,
faraway] están en CRAN y por lo tanto los instalamos con utils::install.packages.
Nos pedirá que elijamos repositorio. Elegimos el que nos guste.
pkgs = c("ggfortify","faraway")
install.packages(pkgs)
Los paquetes [112, multtest] y [34, edgeR] son de Bioconductor. Se
instalan con
source("https://bioconductor.org/biocLite.R")
pkgs = c("multtest","edgeR")
biocLite(pkgs)
keys(org.Hs.eg.db, keytype="SYMBOL")[beginBRCA]
## [1] "BRCA1" "BRCA2" "BRCATA" "BRCA3"
## [5] "BRCA1P1"
Construimos un data.frame con la información pedida.
symbol = keys(org.Hs.eg.db, keytype="SYMBOL")[posBRCA]
entrezid = keys(org.Hs.eg.db, keytype="ENTREZID")[posBRCA]
ensembl = keys(org.Hs.eg.db, keytype="ENSEMBL")[posBRCA]
go = keys(org.Hs.eg.db, keytype="GO")[posBRCA]
data.frame(symbol, entrezid,ensembl,go)
## symbol entrezid ensembl go
## 1 BRCA1 672 ENSG00000235017 GO:0060041
## 2 BRCA2 675 ENSG00000206372 GO:0006101
data(gse20986,package="tamidata")
pacman::p_load("Biobase")
pData(gse20986)[,"tissue"] == "iris" | pData(gse20986)[,"tissue"] == "huvec"
De otro modo:
(sel = which(is.element(pData(gse20986)[,"tissue"],c("iris","huvec"))))
## [1] 1 4 6 10 11 12
eset = gse20986[,sel]
pData(eset)[,"tissue"] = factor(pData(eset)[,"tissue"])
2.Con genefilter::rowttests.
tt = genefilter::rowttests(eset,pData(eset)[,"tissue"])
3.tt1 = multtest::mt.rawp2adjp(tt[,"p.value"],"BH")
tt1$adjp[,2]
sigIH = tt1$index[1:1828]
5.sel = which(is.element(pData(gse20986)[,"tissue"],c("retina","huvec")))
eset = gse20986[,sel]
pData(eset)[,"tissue"] = factor(pData(eset)[,"tissue"])
tt = genefilter::rowttests(eset,pData(eset)[,"tissue"])
tt1 = multtest::mt.rawp2adjp(tt[,"p.value"],"BH")
sigRH = tt1$index[1:sum(tt1$adjp[,2] < 0.05,na.rm = TRUE)]
6.sel = which(is.element(pData(gse20986)[,"tissue"],c("coroides","huvec")))
eset = gse20986[,sel]
pData(eset)[,"tissue"] = factor(pData(eset)[,"tissue"])
tt = genefilter::rowttests(eset,pData(eset)[,"tissue"])
tt1 = multtest::mt.rawp2adjp(tt[,"p.value"],"BH")
sigCH = tt1$index[1:sum(tt1$adjp[,2] < 0.05,na.rm = TRUE)]
7.sigIR = intersect(sigIH,sigRH)
sigIRC = intersect(sigIR,sigCH)
sigIRC
featureNames(gse20986[sigIRC,])
1.tt = genefilter::rowttests(eset,pData(eset)[,"type"])
2.tt = multtest::mt.rawp2adjp(pvalor13,"BH")
pvalor13.BH = tt$adjp[,"BH"]
503
5.intersect(sig13,sig25)
504 APÉNDICE A. SOLUCIONES EJERCICIOS
Bibliografía
505
506 BIBLIOGRAFÍA
519
520 ÍNDICE ALFABÉTICO
sapply, 82
save, 89
setwd, 89
Short-refcard, 10
which, 13
R2HTML, 191
HTML, 192
Región crítica, 455
ReportingTools, 192
finish, 193
HTMLReport, 193
publish, 193
reshape
melt, 54, 85
Robust multichip average (RMA),
63
rowRanges, 111
RStudio, 10
SAM, 155
samr, 158
Selección no específica, 126
Sesgo, 451
SummarizedExperiment
RangedSummarizedExperiment,
110
tami13
AllTami.R, 28
TCGA: The Cancer Genome Atlas,
477
Test de Fisher unilateral, 249
fisher.test, 251
Test de Wald, 456
Test del cociente de verosimilitu-
des, 456
Top-k list, 290
topGO, 279
Variable aleatoria
Bernoulli, 334
discreta
Poisson, 338
Variable Bernoulli, 334
Verosimilitud, 449
522 ÍNDICE ALFABÉTICO
Glosario
Affymetrix http://www.affymetrix.com/. 33
523
524 Glosario