Introducción a R


Acerca de R

R es un ambiente de software libre para hacer cómputo estadístico. R es totalmente gratuito y está disponible para Windows, Mac y Linux. En http://www.r-project.org/ pueden obtener más información acerca de R y descargarlo para instalarlo en sus computadoras.

Vamos a estar trabajando con R, usando una interfaz llamada RStudio que nos ayuda a organizar nuestro trabajo de mejor manera. Este programa también se encuentra disponible gratuitamente para todos los sistemas operativos: http://www.rstudio.com/

En esta sesión nos vamos a enfocar en aprender lo más básico de R, para que podamos usar Bioconductor más cómodamente (Bioconductor es tan solo una serie de paquetes para hacer análisis de relevancia biológica dentro de R).



Empezando con R

Al iniciar RStudio, verán una ventana parecida a la siguiente. Sin importar que sistema operativo usen, la funcionalidad va a ser mas o menos la misma.

En la ventana izquierda de RStudio (la terminal o consola) vamos a teclear los comandos tanto para R como Bioconductor.

En esta página web, haremos uso de dos esquemas de colores para distinguir las instrucciones que podemos escribir o copiar/pegar en R de los resultados que aparecerán en la terminal de R. Las instrucciones que podemos escribir en R se indicarán así:

print("Esta funcion simplemente imprime un texto a la pantalla")

Copien y pegen el texto de arriba en su terminal, y R deberá regresarles algo así:

## [1] "Esta funcion simplemente imprime un texto a la pantalla"

Para obtener ayuda en R de cualquier función, escribimos un signo de interrogación adelante del nombre de la función, por ejemplo:

?print

Dependiendo del sistema operativo que estén usando, la información de ayuda puede aparecer dentro de la misma terminal de R, o en una ventana aparte.

Finalmente, para salirnos de R podemos cerrar la ventana del programa, o escribir cualquiera de estas instrucciones:

q()
quit()

Cuando R les pregunta que si quieren “Save workspace image?”, por ahora digan que no.



Operaciones matemáticas y asignaciones

R es, entre otras cosas, una calculadora. Pueden hacer todas las operaciones básicas:

2+1
## [1] 3

Prueben otras:

3-5
## [1] -2
4*4
## [1] 16
16/4
## [1] 4
7.15 * sqrt(4)
## [1] 14.3

Para guardar uno de estos resultados, tenemos que asignarlo a un “objeto” en R. Podemos darle casi cualquier nombre a los objetos, pero una restricción importante es que no podemos nombrarlos comenzando por un número. Para guardar usamos el símbolo = (aunque también se puede usar <-).

x = 2+1

otro_numero = 7.15 * sqrt(4)

Para ver el contenido de uno de estos objetos, simplemente tecleamos su nombre en R:

otro_numero
## [1] 14.3

La ventaja de guardar así los resultados, es que podemos seguirlos usando en nuevas operaciones:

x + 2*otro_numero
## [1] 31.6

Una de las ventajas de R es que puede realizar operaciones sobre muchos números a la vez. Para ello, primero generamos un objeto que contenga varios números, usando la función c(). Esta instrucción es para combinar.

edades = c(39,36,10,8,1,1,88)

Para ver los números que acabamos de guardar, simplemente tecleamos edades

edades
## [1] 39 36 10  8  1  1 88

y ahora sí, podemos realizar cualquier operación sobre todos a la vez:

edades + 1
## [1] 40 37 11  9  2  2 89
edades * 10
## [1] 390 360 100  80  10  10 880

También hay muchas funciones que podemos usar en R. Una función consta de una palabra, seguida por paréntesis. Ojo, siempre tienen que abrir y cerrar los paréntesis o R no sabrá que están tratando de ejecutar una función. Dentro de los paréntesis van los argumentos, o valores que queremos procesar:

sum(edades)

mean(edades)

max(edades)

min(edades)

range(edades)

sort(edades)

unique(edades)
  • Pueden ver que hace cada una de las funciones de arriba?

Si no saben el nombre de la función que buscan, pueden tratar de encontrarla usando el comando ?? en la terminal:

??deviation
  • Cuál es la función para calcular la “standard deviation”?



Tipos de objectos y manipulación de vectores

Hasta ahora hemos usado solamente valores numéricos. Sin embargo, en R se pueden manejar otros tipos de valores. Por ejemplo, podemos tener valores de texto, los cuales se encierran entre comillas. Del mismo modo que guardamos una serie de números en el objeto edades, podemos guardar una serie de valores de texto en un nuevo objeto:

nombres = c("Homero","Marge","Bart","Lisa","Maggie","Snowball","Abraham")

Muchas veces necesitamos el texto para etiquetar a los valores numéricos (por ejemplo, tener valores numéricos de expresión con etiquetas de texto para los nombres de los genes). Hay una función names() para asignar nombres o etiquetas de texto:

names(edades) = nombres

y ahora si vemos el contenido de edades, veremos que ya tiene sus debidas etiquetas:

edades
##   Homero    Marge     Bart     Lisa   Maggie Snowball  Abraham 
##       39       36       10        8        1        1       88

Nuestro objecto edades tiene la particularidad de que contiene varios valores. A este tipo de objecto se le llama un “vector” en R. Ya vimos que podemos realizar operaciones matemáticas sobre todos los elementos de un vector a la vez. Pero muchas veces queremos manipular sólo una parte del vector. Para extraer partes de un vector, usamos corchetes cuadrados. Por ejemplo:

Para obtener el primer elemento del vector:

edades[1]
## Homero 
##     39

y para obtener el Quinto Elemento:

edades[5]
## Maggie 
##      1

Se puede también obtener una serie de elementos del vector a la vez. Para ello, necesitamos indicarle a R todos los “índices” o posiciones de los elementos que queremos. Y recuerden, cuando queremos usar en R una serie de números (en este caso los índices) necesitamos usar c() para combinarlos. Con todo esto tenemos que:

edades[c(1,5)]
## Homero Maggie 
##     39      1

Por último, podemos usar índices negativos para indicarle a R que queremos quitar temporalmente ciertos elementos de un vector:

edades[-c(1,5)]
##    Marge     Bart     Lisa Snowball  Abraham 
##       36       10        8        1       88


Ejercicios:

  1. Cuál es el promedio de las edades, sin contar el de Maggie?
  2. Quiten a Snowball del vector, ordénenlo y guárdenlo como un nuevo objeto.



Operaciones relacionales

Muchas veces queremos “preguntarle” cosas a los números, como por ejemplo, qué genes tienen un valor de expresión mayor a un umbral. Este tipo de preguntas se contestan mediante operaciones relaciones (mayor que, menor que, igual a, etc). Con nuestro objeto de edades podemos ver esto. Quiénes tienen una edad mayor a 10?

edades
##   Homero    Marge     Bart     Lisa   Maggie Snowball  Abraham 
##       39       36       10        8        1        1       88
edades > 10
##   Homero    Marge     Bart     Lisa   Maggie Snowball  Abraham 
##     TRUE     TRUE    FALSE    FALSE    FALSE    FALSE     TRUE

Del mismo modo podemos preguntar cuales son menores que, mayores o iguales que, o iguales a, un valor:

edades < 10
##   Homero    Marge     Bart     Lisa   Maggie Snowball  Abraham 
##    FALSE    FALSE    FALSE     TRUE     TRUE     TRUE    FALSE
edades >= 10
##   Homero    Marge     Bart     Lisa   Maggie Snowball  Abraham 
##     TRUE     TRUE     TRUE    FALSE    FALSE    FALSE     TRUE
edades == 1    # OJO! Se usa doble signo de igual, para evitar que se asigne 1 a edades
##   Homero    Marge     Bart     Lisa   Maggie Snowball  Abraham 
##    FALSE    FALSE    FALSE    FALSE     TRUE     TRUE    FALSE

En todos estos casos R nos regresa una serie de valores TRUE/FALSE, usualmente llamados valores lógicos. Un vector de valores lógicos puede resultar muy útil, como se verá en los siguientes ejemplos:

sum(edades > 10)
## [1] 3
edades[edades > 10]
##  Homero   Marge Abraham 
##      39      36      88


Ejercicios:

  1. Qué hacen las últimas instrucciones?
  2. Cómo obtienen aquellas edades que son mayores al promedio de todas las edades?



Graficando con R

R es bastante popular por la calidad y variedad de figuras que puede generar. Una vez que nuestros datos están en un objeto en R, es relativamente sencillo hacer figuras con ellos. Por ejemplo, podemos simplemente graficar las edades:

plot(edades)

Verán algo así:

Otros tipos de figuras que pueden generar:

barplot(edades)

pie(edades)

hist(edades)

Todas estas funciones tienen su página de ayuda, accesible por ejemplo con ?hist. También existe una gran cantidad de información avanzada sobre los parámetros que podemos cambiar al graficar, en ?par. Toma tiempo acostumbrarse a todos ellos. Por ahora veamos un ejemplo de complejidad media:

hist(edades, col="skyblue", main="El Histograma Azul", ylab="Personas")

Hay muchas maneras de guardar estas imágenes. Por ejemplo, para guardar la última en un archivo PDF hacemos lo siguiente:

pdf("histograma.pdf")

hist(edades, col="skyblue", main="El Histograma Azul", ylab="Personas")

dev.off()

La función pdf() crea un archivo “histograma.pdf” y todas las instrucciones de graficación que hagamos de ahí en adelante se guardarán en este archivo (y no saldrán en pantalla). Para cerrar el archivo correctamente, tenemos que usar la función dev.off().



Leyendo archivos y manipulando tablas

Por lo general no queremos estar metiendo nuestros datos a mano en R. Si ya tenemos una serie de números en un archivo de texto, los podemos importar a R fácilmente. Para este ejercicio, bajen el archivo num.txt y guárdenlo en el directorio de trabajo de R.

Para esto pueden ser útiles las siguientes funciones, para saber cuál es el directorio de trabajo de nuestra sesión de R y para listar los archivos que se encuentran ahí:

getwd()

list.files()
  • Si ven el archivo “num.txt” en esta lista?

Para importar el contenido de un archivo vamos a usar la función scan():

num = scan("num.txt")
num
##  [1] 252 141 165 174 192 225 176 191 229 170 125 229 176 190 189 239 170
## [18] 233 180 219 229 223 203 161 247 199 224 260 225 327 171 244 170 115
## [35] 272 131 240 173 279  85 175 231 198 214 219 235 171 315 215 206
  • Prueben algunas de las funciones que han venido usando sobre estos números.


Ya para finalizar esta sesión vamos a usar un ejemplo un poco más realista. El archivo tab.txt contiene una tabla de valores de expresión para 50 genes (renglones) en 3 condiciones (columnas). Salven este archivo también en su directorio de trabajo.

Archivos que se encuentren correctamente formateados como tablas (el mismo número de columnas en cada renglón) los podemos leer directamente con read.table():

tab = read.table("tab.txt")

tab
##        cond1 cond2 cond3
## gene1    252   233   182
## gene2    141   179   216
## gene3    165   195   175
## gene4    174   190   188
## gene5    192   231   194
## gene6    225   142   197
## gene7    176   190   218
## gene8    191   210   175
## gene9    229   162   191
## gene10   170   112   192

Una manera de visualizar este tipo de datos es con un boxplot(), que nos muestra la distribución de los valores numéricos en cada columna de una tabla:

boxplot(tab, col=c("red","green","blue"))

Ya habíamos visto que con corchetes cuadrados podemos extraer (con índices positivos) o eliminar (con índices negativos) partes de un vector. Lo mismo podemos hacer para tablas, sin embargo una tabla consta de dos dimensiones: renglones y columnas. En estos casos, los corchetes cuadrados van a aceptar dos series de índicies, separados por una coma:

tab[c(1,6,10), c(1,3)]
##        cond1 cond3
## gene1    252   182
## gene6    225   197
## gene10   170   192

Podemos también especificar índices en sólo una de las dimensiones:

tab[c(1,6,10), ]

tab[, c(1,3)]           # OJO, no se les olvide poner la primera coma


Ejercicios:

  1. Muestren los valores de expresión del 3er gen
  2. Cuál es el promedio de expresión en la 2da condición?
  3. Cuántos genes tienen un valor de expresión mayor en la primera condición comparada con la tercera?

  4. Avanzado: Revisen la ayuda de la función apply() para averiguar como calcular el promedio de expresión de cada uno de los genes, con una sola instrucción. Y para cada una de las condiciones?