Introducción a R

author: Javier Ballesteros date: agosto-septiembre 2015

Objetivos generales del curso

Contenidos del curso

  1. Introducción a R y a sus tipos básicos de datos
  2. Vectores
  3. Matrices
  4. Factores
  5. Listas
  6. Estructuras rectangulares de datos (data frames)

Descarga e instalación de R y RStudio

R: www.r-project.org

RStudio: www.rstudio.com

Introducción a R

R funciona con interfaz de línea de comandos en vez de con interfaz gráfica (GUI)

R como software libre

RStudio

RStudio es una herramienta de libre acceso que representa un ambiente integrado de desarrollo (Integrated Development Environment o IDE), que hace más fácil:

RStudio unifica los componentes de R en un IDE

Lo que hace más eficaz y eficiente el trabajo con R

R y RStudio para investigación reproducible

Investigación reproducible (reproducible research): enlaza instrucciones específicas para el análisis de datos a las bases de datos, y genera informes del análisis que pueden ser reproducidos y verificados

Programación educada (literate programming): metodología que combina un lenguaje de programación (Python, R, …) con un lenguaje de documentación (Latex, Markdown, …)

Markdown en RStudio

Páginas web interesantes

Ayuda general en R

Se puede utilizar Google para buscar información sobre funciones o paquetes de R. Se recomienda utilizar r: o r- como prefijo. Por ejemplo r: meta-analysis

R se estructura en base a funciones

Una función de R está compuesta por su nombre y (entre paréntesis) sus posibles argumentos separados por comas:

El nombre de la función es t.test, y sus opciones o argumentos implican una fórmula y ~ x, un test para grupos independientes paired = FALSE, que asume varianzas iguales var.equal = TRUE, y que las variables y y x cuya asociación se quiere estudiar se encuentran en data = mis.datos

Argumentos en una función de R

Hay 2 tipos de argumentos:

Ayuda específica para funciones

La ayuda de una función proporciona diversas informaciones - algunas más crípticas que otras. Por ejemplo, la función t.test puede ser utilizada para:

Ayuda para el t-test (?t.test)

Trabajando con librerías - packages externos

Directorio de trabajo

R trabaja en un directorio por defecto o especificado.

Manejo básico de la sesión con R

Operaciones con R

R como calculadora

R puede verse como una calculadora vectorizada que utiliza las reglas comunes de precedencia de operaciones

35*12;35*12+4;35*(12+4)
[1] 420
[1] 424
[1] 560
exp(0.95)*2^10
[1] 2647.767

R como calculadora. Operadores comunes

Asignación de objetos -> generación de variables

Ninguna de las operaciones anteriores se ha conservado en memoria. R evalúa una instrucción y devuelve un valor. Para mantener esos valores en memoria hay que asignarlos a un objeto. La asignación se realiza con un símbolo compuesto por los símbolos menor que < y guión alto -

y <- c(1:10)
y1 <- y * 10
y; y1
 [1]  1  2  3  4  5  6  7  8  9 10
 [1]  10  20  30  40  50  60  70  80  90 100

R es un lenguaje orientado a objetos

Estructuras de datos en R

Estructuras de datos en R: clases

Vectores en R

Hay 4 tipos principales de vectores en R

Generación de vectores / variables

Las maneras más comunes de generar un vector son por la combinación, secuencia, o repetición de valores

Generación de vectores numéricos: función c()

y <- c(1:10)
y1 <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
y; y1
 [1]  1  2  3  4  5  6  7  8  9 10
 [1]  1  2  3  4  5  6  7  8  9 10
class(y); class(y1)
[1] "integer"
[1] "numeric"

Generación de vectores numéricos: secuencias regulares

y <- seq(from=1, to=10, by=1)
y
 [1]  1  2  3  4  5  6  7  8  9 10
class(y)
[1] "numeric"

Generación de vectores numéricos: secuencias repetidas

y <- rep(1:2, each=5)
y
 [1] 1 1 1 1 1 2 2 2 2 2
class(y)
[1] "integer"

Generación de vectores lógicos y operaciones lógicas

Se pueden generar de manera individual o por la aplicación de condiciones lógicas a otro vector. Presentan los valores TRUE y FALSE con los valores 1 y 0 respectivamente Las operaciones lógicas son las habituales: <, <=, >, >=, ==, !=, y con conjuntos: intersección &, unión |, y negación !

Generación de vectores lógicos y operaciones lógicas

y <- 1:10; y1 <- y > 5; y; y1
 [1]  1  2  3  4  5  6  7  8  9 10
 [1] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
class(y); class(y1)
[1] "integer"
[1] "logical"

Generación de vectores carácter (alfanuméricos)

names <- c("Juan", "Pedro", "Maria")
names
[1] "Juan"  "Pedro" "Maria"
class(names)
[1] "character"

Valores perdidos o missing

En general las operaciones con valores missing NA o NaN devuelven un valor missing

y <- c(1:9, NA)
y
 [1]  1  2  3  4  5  6  7  8  9 NA
sum(y)
[1] NA
mean(y)
[1] NA

Operaciones que generan NaN

0/0
[1] NaN
Inf - Inf
[1] NaN

Valores missing

Las funciones que utilizan la estructura de formula para definir relaciones entre variables \(y \sim x\), toman en cuenta los valores missing, pero no funciones simples como las de estadística descriptiva u operaciones matemáticas. Siempre es aconsejable saber como es la estructura de valores perdidos en nuestros datos. La función summary() devuelve esa información. Un argumento general para no tomar en cuenta los valores perdidos es na.rm=TRUE

Valores missing

y <- c(1:9, NA)
is.na(y)
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
sum(is.na(y))
[1] 1

Funciones importantes para valores numéricos

Funciones importantes para valores numéricos

Funciones importantes para valores numéricos

Vectores de cadenas de carácteres (strings) y su importación como factores

Los vectores de cadenas de carácteres se importan a R por defecto como factores, lo que no siempre es lógico o aconsejable

Dentro de la función dataframe() , o relacionadas, utilizar el argumento stringsAsFactors = FALSE para eliminar esa opción por defecto, y convertir manualmente con la función factor() los vectores de carácteres que realmente sean variables categóricas

Factores

Factores en R

R presenta una estructura específica de datos para variables categóricas que son los factores, cuyos valores están incluidos entre “”, y que se generan con la función factor(). La función factor() ordena los niveles del factor alfabéticamente

sex <- c("F", "F", "F", "F", "M", "M")
sex.factor <- factor(sex, labels=c("Female", "Male"))
class(sex); class(sex.factor)
[1] "character"
[1] "factor"

Factores en R

summary(sex)
   Length     Class      Mode 
        6 character character 
summary(sex.factor)
Female   Male 
     4      2 

Cambio en el orden de los niveles del factor: levels()

La función levels() (o argumento dentro de la función factor()), permite cambiar el orden (alfabético) en el que se recogen los valores del factor

sex <- c("F", "F", "F", "F", "M", "M")
sex.factor <- factor(sex, levels=c("M", "F"), labels=c("Male", "Female"))
summary(sex.factor)
  Male Female 
     2      4 

Cambio en el orden de los niveles del factor: relevel()

La función relevel() permiten cambiar el orden (alfabético) en el que se recogen los valores del factor

sex <- c("F", "F", "F", "F", "M", "M")
sex.factor <- factor(sex, labels=c("Female", "Male"))
sex.factor <- relevel(sex.factor, ref="Female")
summary(sex.factor)
Female   Male 
     4      2 

Factores nominales y ordinales: argumento “ordered”

Un factor que presente categorías ordenadas se obtiene en R con el argumento ordered

vector.ordered <- c("high", "high", "low", "low", "medium")
factor.ordered <- factor(vector.ordered, order=TRUE, levels=c("low", "medium", "high"), labels=c("Bajo", "Medio", "Alto"))
summary(factor.ordered)
 Bajo Medio  Alto 
    2     1     2 

Codificación interna de los niveles de factores

Los niveles de los factores se representan internamente por números enteros positivos (1, 2,…). La función as.numeric() cambia del modo factor al modo numérico las categorías de un factor. La función as.factor() cambia una variable numérica que representa niveles de categorías a una variable de tipo factor sin necesidad de definirla previamente como factor. Este cambio de factor a numérico es importante en el análisis de tendencias lineales o relaciones dosis-efecto en modelos lineales anidados

Operaciones sobre factores

Indexación de vectores: selección de valores para un único elemento

Se realiza con la expresión vector[i] donde i es la posición del elemento que se quieren indexar

x <- 1:10
x
 [1]  1  2  3  4  5  6  7  8  9 10
x[5]; x[8]
[1] 5
[1] 8

Indexación de vectores: selección de valores para múltiples elementos

Se realiza con la expresión vector[i] donde i contiene ahora múltiples elementos

x <- 1:10
x[c(1, 3, 5)]
[1] 1 3 5
x[1:5]
[1] 1 2 3 4 5

Indexación de vectores por condiciones lógicas

x <- 1:10
x1 <- x > 5; x1
 [1] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
x[x1]
[1]  6  7  8  9 10

Indexación de vectores: modificación de valores mediante asignación a índices

Se realiza con la expresión vector[i] donde i es la posición o posiciones de los elementos que se quieren indexar

y <- rnorm(10); mean(y); y[10]
[1] 0.3233025
[1] 1.178389
y[10] <- 10; mean(y)
[1] 1.205464

Recordatorio de las principales funciones generales para vectores en R

Matrices

Una matriz de dimensión \(r \times c\), se genera con la función matrix(), o uniendo un conjunto de vectores con la función cbind(), o un conjunto de observaciones con la función rbind(). Todos sus elementos son numéricos

La sintaxis general de la función matrix es: matrix(data, nrow, ncol, byrow=F)

Matrices: función matrix()

A <- matrix(c(1, 3, 5, 7), nrow=2, byrow=T)
A
     [,1] [,2]
[1,]    1    3
[2,]    5    7

Matrices: función cbind()

a <- rep(1, 10)
b <- rnorm(10)
B <- cbind(a, b)
B
      a          b
 [1,] 1  0.8372790
 [2,] 1 -1.5891612
 [3,] 1  0.3444779
 [4,] 1  0.3005216
 [5,] 1  0.9383893
 [6,] 1  1.1463592
 [7,] 1 -0.4164933
 [8,] 1 -1.3625502
 [9,] 1  0.8350266
[10,] 1 -0.8900460

Matrices: función rbind()

C <- rbind(a[1:4], b[1:4])
C
         [,1]      [,2]      [,3]      [,4]
[1,] 1.000000  1.000000 1.0000000 1.0000000
[2,] 0.837279 -1.589161 0.3444779 0.3005216

Nombres de columnas y filas de la matriz: rownames() y colnames()

Además de informar y servir también para indexar la matriz, el nombrar las filas y columnas es interesante en el análisis secundario de datos publicados:

tabla <- matrix(c(10, 30, 5, 28), nrow=2) # tabla 2x2
rownames(tabla) <- c("Resp +", "Resp -")
colnames(tabla) <- c("Exp", "Ctrl")
tabla
       Exp Ctrl
Resp +  10    5
Resp -  30   28

Matrices: operaciones en filas y columnas

Indexación de matrices

Al igual que con vectores con el operador [, sólo que al ser las matrices bidimensionales se necesitan 2 índices, uno para las filas y otro para las columnas m[i, j]

A <- matrix(c(1:10), nrow=2)
A
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    3    5    7    9
[2,]    2    4    6    8   10
A[2, 3] # 1 elemento específico
[1] 6

Indexación de matrices

A[, c(1,3)] # todas las filas, algunas columnas
     [,1] [,2]
[1,]    1    5
[2,]    2    6
A[1,] # primera fila, todas las columnas
[1] 1 3 5 7 9

Indexación de matrices

A <- matrix(1:6, nrow=3)
A
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6
ind <- c(TRUE, FALSE, TRUE, FALSE,TRUE, FALSE)
A[ind]
[1] 1 3 5

Operaciones matemáticas con matrices

Además de las propias de algebra matricial, las operaciones matemáticas simples de una matriz y un escalar, y entre matrices, siguen - como en el caso de los vectores - una estructura de operaciones individuales:

A <- matrix(c(1:12), nrow=3)
A
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

Operaciones matemáticas con matrices

A*5
     [,1] [,2] [,3] [,4]
[1,]    5   20   35   50
[2,]   10   25   40   55
[3,]   15   30   45   60
A/10
     [,1] [,2] [,3] [,4]
[1,]  0.1  0.4  0.7  1.0
[2,]  0.2  0.5  0.8  1.1
[3,]  0.3  0.6  0.9  1.2

Operaciones matemáticas con matrices

B <- matrix(c(1:12), nrow=3)
B
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
A + B
     [,1] [,2] [,3] [,4]
[1,]    2    8   14   20
[2,]    4   10   16   22
[3,]    6   12   18   24

Recordatorio de las principales funciones para matrices en R

Listas

Una lista en R es un objeto que contiene una colección ordenada de objetos que -normalmente- tienen diversas estructuras (vectores, matrices,…), y longitudes

Para este curso el principal interés de una lista es que de esa manera se recogen y presentan los resultados de distintos modelos y funciones en R, y es también una forma de devolver resultados a partir de funciones programadas

Listas

La manera más simple de generar una lista es usar la función list() para combinar objetos

mi.lista <- list(curso="Intro R", sitio="ULH", semanas=2, requerido=T)
mi.lista
$curso
[1] "Intro R"

$sitio
[1] "ULH"

$semanas
[1] 2

$requerido
[1] TRUE

Indexación de listas

Data frames

Data frames: estructuras rectangulares de datos, observaciones por variables

Una base de datos rectangular (filas por columnas) es una lista de clase data.frame en la que sus componentes son vectores (numéricos, carácter, o lógicos) o factores de la misma longitud. La diferencia básica entre una data frame y una matriz, es que la matriz sólo puede contener valores numéricos, restricción que no se aplica a una data frame, ya que puede contener elementos de distinto tipo

Una data frame puede ser generada con la función data.frame(), aunque normalmente es importada de otras bases de datos

Importar/exportar data frames

Importar/exportar data frames: recomendaciones

Tamaño aproximado de una base de datos importada

Necesario para saber si los datos se ajustan a la memoria del ordenador. El cálculo aproximado del espacio RAM necesario asumiendo variables numéricas (8 bytes) es: - Número de bytes \(\small{\sim}\) número filas \(\small{\times}\) número columnas \(\small{\times}\) 8 - Kilobytes (KB) = bytes/10^3 - Megabytes (MB) = bytes/10^6 - Gigabytes (GB) = bytes/10^9

Descripción básica de una base de datos

Función data.frame()

Añade vectores de columna

y <- round(rnorm(8, 25, 4))
grupo <- rep(1:2, each=4)
edad <- round(rnorm(8, 40, 5))
data <- data.frame(y, grupo, edad)
data
   y grupo edad
1 28     1   30
2 24     1   45
3 30     1   44
4 24     1   41
5 22     2   42
6 31     2   43
7 24     2   42
8 28     2   44

Funciones importantes para una data frame: head()

head(data) # 6 primeros registros
   y grupo edad
1 28     1   30
2 24     1   45
3 30     1   44
4 24     1   41
5 22     2   42
6 31     2   43

Funciones importantes para una data frame: tail()

tail(data) # 6 últimos registros
   y grupo edad
3 30     1   44
4 24     1   41
5 22     2   42
6 31     2   43
7 24     2   42
8 28     2   44

Funciones importantes para una data frame: dim()

dim(data) # observaciones x variables
[1] 8 3

Funciones importantes para una data frame: str()

str(data) # estructura del objeto
'data.frame':   8 obs. of  3 variables:
 $ y    : num  28 24 30 24 22 31 24 28
 $ grupo: int  1 1 1 1 2 2 2 2
 $ edad : num  30 45 44 41 42 43 42 44

Indexación de data frames

name <- c("Ana", "Pedro", "Jose", "Julia", "Maria") # variable string/cadena
age <- c(28, 30, 21, 39, 35) # variable numérica
child <- c(FALSE, TRUE, TRUE, FALSE, TRUE) # variable lógica
people <- data.frame(name, age, child, stringsAsFactors=FALSE)
people
   name age child
1   Ana  28 FALSE
2 Pedro  30  TRUE
3  Jose  21  TRUE
4 Julia  39 FALSE
5 Maria  35  TRUE

Indexación de data frames: selección y modificación de subconjuntos de datos

str(people)
'data.frame':   5 obs. of  3 variables:
 $ name : chr  "Ana" "Pedro" "Jose" "Julia" ...
 $ age  : num  28 30 21 39 35
 $ child: logi  FALSE TRUE TRUE FALSE TRUE

Indexación de data frames: operador [

Se realiza con la expresión dataframe[r,c] donde r indiza el número de fila ,y c indexa el número de columna. La instrucción data[1:10, 1:10] selecciona las 10 primeras filas, y las 10 primeras columnas de data. La instrucción data[1:10,] selecciona las 10 primeras filas y todas las columnas de data. La instrucción data[, 1:10] selecciona todas las filas, pero sólo las 10 primeras columnas. En todos los casos el operador [ devuelve otra data frame

Indexación de data frames: [

people[1:2,]
   name age child
1   Ana  28 FALSE
2 Pedro  30  TRUE
people[3, 2]
[1] 21
people[, c(1, 3)]
   name child
1   Ana FALSE
2 Pedro  TRUE
3  Jose  TRUE
4 Julia FALSE
5 Maria  TRUE

Indexación de data frames: [[ y $

Los operadores [[ y $ devuelven un objeto, en este caso un vector de una data frame

people[["age"]]
[1] 28 30 21 39 35
people[[2]]
[1] 28 30 21 39 35
people$age
[1] 28 30 21 39 35

Indexación de data frames: subset()

La función subset() se puede utilizar para seleccionar subconjuntos de valores de vectores, matrices y data frames, en base a condiciones lógicas

people$age
[1] 28 30 21 39 35
subset(people, age > 30)
   name age child
4 Julia  39 FALSE
5 Maria  35  TRUE

Selección de subgrupos por condiciones lógicas

El argumento subset de la función subset(), selecciona observaciones, mientras que el argumento select selecciona variables

Añadir nuevas variables a una data frame mediante indexación y asignación

height <- c(163, 177, 163, 162, 157)
people$height <- height
people[["height"]] <- height
people
   name age child height
1   Ana  28 FALSE    163
2 Pedro  30  TRUE    177
3  Jose  21  TRUE    163
4 Julia  39 FALSE    162
5 Maria  35  TRUE    157

Añadir nuevas variables a una data frame mediante la función cbind()

cbind() sólo genera data frames si uno de los argumentos lo es, en otro caso genera una matriz

weight <- c(74, 63, 68, 55, 56)
cbind(people, weight)
   name age child height weight
1   Ana  28 FALSE    163     74
2 Pedro  30  TRUE    177     63
3  Jose  21  TRUE    163     68
4 Julia  39 FALSE    162     55
5 Maria  35  TRUE    157     56

Añadir nuevas observaciones a una data frame mediante la función rbind()

rbind() sólo genera data frames si uno de los argumentos lo es, en otro caso genera una matriz. Es más compleja que cbind(), consiste en pegar 2 data frames con el mismo nombre para las variables

new.obs <- data.frame(name="Tomas", age=37, child=FALSE, height=183)
rbind(people, new.obs)
   name age child height
1   Ana  28 FALSE    163
2 Pedro  30  TRUE    177
3  Jose  21  TRUE    163
4 Julia  39 FALSE    162
5 Maria  35  TRUE    157
6 Tomas  37 FALSE    183

Unión de bases de datos mediante la función merge()

Hay 2 posibilidades para unir bases de datos, (1) que sean independientes (por ejemplo las bases de datos de los distintos centros de un estudio multicéntrico, es decir que añadimos observaciones), o (2) que sean dependientes (por ejemplo las bases de datos de las distintas visitas realizadas en cada uno de los centros, es decir añadimos columnas). En ambos casos la función merge() resuelve la tarea

Función merge(): unión de datos independientes añadiendo observaciones

id <- 1:3; v1 <- round(rnorm(3, 25, 4)); v2 <- v1-5; v3 <- v1-10
data1 <- data.frame(id, v1, v2, v3)
id <- 4:6; v1 <- round(rnorm(3, 25, 4)); v2 <- v1-5; v3 <- v1-10
data2 <- data.frame(id, v1, v2, v3)
data <- merge(data1, data2, all.x=T, all.y=T)
data
  id v1 v2 v3
1  1 27 22 17
2  2 31 26 21
3  3 33 28 23
4  4 22 17 12
5  5 26 21 16
6  6 21 16 11

Función merge(): unión de datos relacionados añadiendo columnas

id <- 1:5; v1 <- round(rnorm(5, 25, 4)); v2 <- v1-5; v3 <- v1-10
visit1 <- data.frame(id, v1)
visit2 <- data.frame(id, v2)
visit3 <- data.frame(id, v3)
data <- merge(visit1, visit2, by="id")
data1 <- merge(data, visit3, by="id")
data1
  id v1 v2 v3
1  1 24 19 14
2  2 26 21 16
3  3 22 17 12
4  4 20 15 10
5  5 29 24 19

Ordenar una data frame según una variable

nombre <- c("Juan", "Tomas", "Virginia", "Leyre")
edad <- c(45, 35, 28, 52)
data <- data.frame(nombre, edad)
data
    nombre edad
1     Juan   45
2    Tomas   35
3 Virginia   28
4    Leyre   52

Ordenamiento con la función order()

data[order(data$edad),]
    nombre edad
3 Virginia   28
2    Tomas   35
1     Juan   45
4    Leyre   52

Referencias

Referencias para usuarios de otros paquetes estadísticos