Introducción a programación en R

Algunas ideas para empezar a programar en lenguaje R

IMPORTANTE! para buscar ayuda de una función se debe escribir ?nombre_de_funcion. El cógigo se puede comentar usando el simbolo de numeral '#'

In [1]:
#Esto es un comentario antes de la línea de código que muestra la ayuda de la función seq() 
?seq

R se puede usar como calculadora

La estructura más básica en R es el "Vector". A partir de los vectores se pueden crear estructuras más complejas de varias dimensiones. Un número o letra cualquiera en R es tratado como un vector de un elemento. Y con estos vectores se pueden hacer operaciones (matemáticas en el caso de números y de textos en el caso de cadenas). También se pueden declarar asignar los números a variables, más conocidas en R como objetos. Para asignar valores a una variable se realiza por medio del símbolo "<-" (como una flecha hacia la izquierda) o tan solo con el signo "="

Por ejemplo: sumemos los números 5 y 2 de tres formas diferentes.

In [2]:
# 1. Operaciones directas con números
5 + 2

# 2. Operaciones con números declarados como variables
x <- 5
y <- 2
x + y

# 3. Operación con los dos números almacenados en una sola variable usando una función

numeros <- c(5, 2)
sum(numeros)
Out[2]:
7
Out[2]:
7
Out[2]:
7

Operadores especiales de R

Al igual que otros lenguajes, R dispone de operadores especiales que le permiten interpretar las sentencias que el usuario escribe.

R se basa en las operaciones "uno a uno"; es decir, si tenemos varios elementos e un vector y los queremos multiplicar por otro vector con la misma cantidad de elementos, la operación será: el elemento i del primer vector con el elemento i del segundo vector.

In [3]:
x2 = 1:5 #Esto es un vector de 5 elementos (es creado con la estructura especial i:n de R)
y2 = 5:1 #Esto también es un vector de 5 elementos. Si el inicio es mayor, la secuencia es descendente
x2
y2
Out[3]:
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
Out[3]:
  1. 5
  2. 4
  3. 3
  4. 2
  5. 1

Las operaciones con vectores de varios elementos también se realizan elemento a elmento. Esto permite operar entre vectores cuya longitudes sean múltiplos entre sí. Ejemplo, una multiplicación de un vector de 5 elementos con otro de 10 elementos. En estos casos, se reusan los valores del vector mas pequeño hasta completar el total del vector más grande. Veamos como funciona con la multiplicación de los vectore $x2$ y $y2$:

In [4]:
x2 = 1:5
x2 # Para mostrar el resultado almacenado en la variable x2

y3 = 15:1
y3 # Para mostrar el resultado almacenado en la variable y3

z = x2 * y3
z # Para mostrar el resultado almacenado en la variable z
Out[4]:
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
Out[4]:
  1. 15
  2. 14
  3. 13
  4. 12
  5. 11
  6. 10
  7. 9
  8. 8
  9. 7
  10. 6
  11. 5
  12. 4
  13. 3
  14. 2
  15. 1
Out[4]:
  1. 15
  2. 28
  3. 39
  4. 48
  5. 55
  6. 10
  7. 18
  8. 24
  9. 28
  10. 30
  11. 5
  12. 8
  13. 9
  14. 8
  15. 5

Cuando los vectores no tienen longitudes múltiplos entre sí, R realiza la operación de igual manera, pero muestra una advertencia diciendo que los vetores no son múltiplos entre sí. Entonces, el resultado de los últimos valores podría no ser el deseado. Aquí va un ejemplo:

In [5]:
# Operaciones con vectores de diferente longitud pero no múltiplos entre ellos.
x3 = 1:15
x3
y2 = 1:4
x3 * y2
Out[5]:
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
Warning message:
In x3 * y2: longer object length is not a multiple of shorter object length
Out[5]:
  1. 1
  2. 4
  3. 9
  4. 16
  5. 5
  6. 12
  7. 21
  8. 32
  9. 9
  10. 20
  11. 33
  12. 48
  13. 13
  14. 28
  15. 45

Los textos también se pueden almacenar como vectores y asignar a variables. El tipo de dato en este caso será un character (Ya veremos los diferentes tipos de datos usados en R).

In [6]:
#esto es una cadena
cadena = 'Elefante se balanceaba sobre la tela de una araña'
cadena
Out[6]:
'Elefante se balanceaba sobre la tela de una araña'

Existen funciones con las cuales también se puede ejecutar tareas con vectores de caracteres. Por ejemplo si a cada valor de la variable $x3$ le queremos agregar el contenido de la variable $cadena$ se puede usar la función paste, lo cual daría como resultado lo siguiente:

In [7]:
# Combinar vectores como caracteres
paste(x3, cadena)

# Los valores numéricos del vector x3 se convierten internamente en caracteres que se pueden juntar a los caracteres del objeto 'cadena'
Out[7]:
  1. '1 Elefante se balanceaba sobre la tela de una araña'
  2. '2 Elefante se balanceaba sobre la tela de una araña'
  3. '3 Elefante se balanceaba sobre la tela de una araña'
  4. '4 Elefante se balanceaba sobre la tela de una araña'
  5. '5 Elefante se balanceaba sobre la tela de una araña'
  6. '6 Elefante se balanceaba sobre la tela de una araña'
  7. '7 Elefante se balanceaba sobre la tela de una araña'
  8. '8 Elefante se balanceaba sobre la tela de una araña'
  9. '9 Elefante se balanceaba sobre la tela de una araña'
  10. '10 Elefante se balanceaba sobre la tela de una araña'
  11. '11 Elefante se balanceaba sobre la tela de una araña'
  12. '12 Elefante se balanceaba sobre la tela de una araña'
  13. '13 Elefante se balanceaba sobre la tela de una araña'
  14. '14 Elefante se balanceaba sobre la tela de una araña'
  15. '15 Elefante se balanceaba sobre la tela de una araña'

Objetos y tipos de datos en R

Los objetos en R son las variables declaradas mediante cualquiera de los operadores de asignación ('<-' o '='). Ya habíamos empleado estos operadores para asignar los ejemplos anteriores. Aunque ambos operadores funcionan bien, se ha extendido el uso del operador '<-' para evitar confundir con el operador de comparación '==' (se comentará al respecto en su tiempo).

En R se manejan diferentes tipos de estructuras de datos (Wickham, 2014):

Dimensiones Homogeneos Heterogeneos
1 dim vector Lista
2 dim Matriz Data frame
n dim Arreglos

Estas formas básicas de estructuras de datos permiten construir objetos más completos como las Formulas, Expresiones, Funciones, y otros más complejos...

Dentro de las estructuras pueden usar diferentes tipos de datos, por ejemplo:

Tipo de dato Ejemplo Vector Lista Matriz Data frame Arreglo
Números enteros 1, 2, 3 x x x x x
Números reales 0.1, 0.5, x x x x x
Números complejos 3+2i x x x x x
Booleanos TRUE, FALSE x x x x x
Caracteres 'Textos' x x x
Fecha 2001-04-03 x x x
Fecha y tiempo '2016-01-01 23:00' x x x
In [8]:
# Vectores se crean con la funcion c(). 
#Otras funciones también producen como resultado vectores, por ejemplo la función seq()
enteros <- c(1L,4L,5L,3L)
reales <- c(0,0.5,1.2,1.3)
complejos <- c(1+0i, 3+2i, 5+1i, 3+1i)
booleanos <- c(TRUE, FALSE, FALSE, T)
caracteres <- c('Alex', 'Carlos', 'Manuel','Andrés')
fecha <- c(as.Date('2001-04-03','2005-05-01','2016-03-28','2015-12-31', format = '%Y-%m-%d'))
fecha_tiempo <- c(seq(as.POSIXct('2016-01-01'), as.POSIXct('2016-01-01 23:00'), by = '6 hour'))
In [9]:
# Listas se crean con la función list()
lista <- list(enteros, reales, complejos, booleanos, caracteres, fecha, fecha_tiempo)
str(lista) # la función str() permite consultar el tipo de estructura y dato almacenado en un objeto.
List of 7
 $ : int [1:4] 1 4 5 3
 $ : num [1:4] 0 0.5 1.2 1.3
 $ : cplx [1:4] 1+0i 3+2i 5+1i ...
 $ : logi [1:4] TRUE FALSE FALSE TRUE
 $ : chr [1:4] "Alex" "Carlos" "Manuel" "Andrés"
 $ : Date[1:1], format: "2001-04-03"
 $ : POSIXct[1:4], format: "2016-01-01 00:00:00" "2016-01-01 06:00:00" ...
In [10]:
# Arreglos se crean con al función array()
mi_arreglo <- array(x3, dim=c(3,3,2))
mi_arreglo
Out[10]:
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 1
  17. 2
  18. 3
In [11]:
# Matrices se crean con la función matrix()
matrix(x3, nrow = 3, byrow = F)
matrix(x3, nrow = 3, byrow = T)
matrix(1:15, nrow = 4, byrow = T) #La secuencia 1:15 no es múltiplo del número de columnas o filas
Out[11]:
1 4 71013
2 5 81114
3 6 91215
Out[11]:
12345
6 7 8 910
1112131415
Warning message:
In matrix(1:15, nrow = 4, byrow = T): data length [15] is not a sub-multiple or multiple of the number of rows [4]
Out[11]:
1234
5678
9101112
131415 1
In [12]:
# Data frames se crean con la función data.frame()
data_frame <- data.frame(enteros, reales, complejos, booleanos, caracteres, fecha, fecha_tiempo)
str(data_frame)
data_frame
'data.frame':	4 obs. of  7 variables:
 $ enteros     : int  1 4 5 3
 $ reales      : num  0 0.5 1.2 1.3
 $ complejos   : cplx  1+0i 3+2i 5+1i ...
 $ booleanos   : logi  TRUE FALSE FALSE TRUE
 $ caracteres  : Factor w/ 4 levels "Alex","Andrés",..: 1 3 4 2
 $ fecha       : Date, format: "2001-04-03" "2001-04-03" ...
 $ fecha_tiempo: POSIXct, format: "2016-01-01 00:00:00" "2016-01-01 06:00:00" ...
Out[12]:
enterosrealescomplejosbooleanoscaracteresfechafecha_tiempo
1101+0iTRUEAlex2001-04-032016-01-01
240.53+2iFALSECarlos2001-04-032016-01-01 06:00:00
351.25+1iFALSEManuel2001-04-032016-01-01 12:00:00
431.33+1iTRUEAndrés2001-04-032016-01-01 18:00:00
In [13]:
# Formulas se usan como instrucciones de cálculo
mi_formula <- formula(ordenada ~ abcisa^3+ abcisa^2 + abcisa + 0.5)
str(mi_formula)
mi_formula
Class 'formula' length 3 ordenada ~ abcisa^3 + abcisa^2 + abcisa + 0.5
  ..- attr(*, ".Environment")=<environment: R_GlobalEnv> 
Out[13]:
ordenada ~ abcisa^3 + abcisa^2 + abcisa + 0.5
In [14]:
# Expresionesse usan para mostrar el resultado en forma matemática
mi_expresion <- expression(abcisa^3+ abcisa^2 + abcisa + 0.5)

cat('\nEsta es la estructura de la expresión...\n\n')
str(mi_expresion)
Esta es la estructura de la expresión...

  expression(abcisa^3 + abcisa^2 + abcisa + 0.5)

Así es como se muestra el resultado interpretado $$abcisa^3 + abcisa^2 + abcisa + 0.5$$

In [15]:
# R permite programar nuestros propios procedimientos y declararlos como objetos con mediante "function()

my_funcion <- function(base, altura){
    #procedimiento para calcular el área de un triángulo
    return((base * altura)/2)
}

my_funcion(5,6) #Usar la función que programamos para calcular el área de un triángulo de base 5 y altura 6
Out[15]:
15

Gráficos básicos

Una de las fortalezas de R (aparte de la estadística) es la generación de gráficos complejos. Existen muchísimas opciones para mostrar los datos en forma de gráfico. El gráfico más básico muestra una vector numerico en forma de puntos; donde los elementos vector se grafican como la serie ordenada y la posición de cada elemento en el vector se emplea como la abcisa. Veamos con ejemplos:

In [16]:
options(repr.plot.width = 5) #Esto solo es para hacer más pequeñas las imágenes en el Notebook de Júpiter
options(repr.plot.height = 3.5) #Esto solo es para hacer más pequeñas las imágenes en el Notebook de Júpiter

#La función plot(), requiere al menos un vector x
serie = seq(1,10,by= 0.25) #la función seq() crea un vector ordenado de valores en pasos iguales
plot(serie, type = 'o') #type = "o", es para indicar que se tracen un gráfico de puntos y líneas

# Ahora un gráfico indicando la abcisa y la ordenada
abcisa = serie
ordenada = abcisa^3+ abcisa^2 + abcisa + 0.5
plot(abcisa, ordenada, type = 'o')

abcisa2 = runif(100) #la función runif() crea vectores numéricos aleatorios
ordenada2 = abcisa2^3+ abcisa2^2 + abcisa2 + 0.5
plot(abcisa2, ordenada2, type = 'o')
In [17]:
options(repr.plot.width = 5) #Esto solo es para hacer más pequeñas las imágenes en el Notebook de Júpiter
options(repr.plot.height = 3.5) #Esto solo es para hacer más pequeñas las imágenes en el Notebook de Júpiter

#la función curve() permite graficar una ecuación en función de una serie de valores x

curve(sin(x), from = 0, to = 10)
curve(cos(x), from = 0, to = 10, add = TRUE, col='blue')
curve(x^3/(x^2 + 1), -2, 2, add = F, col='blue')

Gráficos avanzados

Otras librerías se permiten crear agregar funciones nuevas para el trazado de gráficos. Se requiere instalar ciertas librerías nuevas, como por ejemplo 'lattice', 'ggplot2', etc.... Para instalar necesitamos la función install.packages()

In [18]:
#Instalar paquetes adicionales

install.packages('lattice')
install.packages('ggplot2')
install.packages('plotly')
In [19]:
# Gráficos con lattice tomado de Kabacoff R. (2014) 

library(lattice) # Con la función library() se cargan los paquetes adicionales
In [20]:
options(repr.plot.width = 5) #Esto solo es para hacer más pequeñas las imágenes en el Notebook de Júpiter
options(repr.plot.height = 4) #Esto solo es para hacer más pequeñas las imágenes en el Notebook de Júpiter

# Ejjemplor Lattice
attach(mtcars)

par(mfrow = c(3,3))

# Crear factores
gear.f<-factor(gear,levels=c(3,4,5),
   labels=c("3gears","4gears","5gears"))
cyl.f <-factor(cyl,levels=c(4,6,8),
   labels=c("4cyl","6cyl","8cyl"))

# 3d scatterplot por nivel de factores
cloud(mpg~wt*qsec|cyl.f,
   main="3D Scatterplot by Cylinders")
In [ ]:
# Gráficos con ggplot2

library(ggplot2) # Con la función library() se cargan los paquetes adicionales
library(ggthemes) #ggthemes es una librería complementaria a ggplot que tiene preformateados temas de gráficos
In [22]:
options(repr.plot.width = 5) #Esto solo es para hacer más pequeñas las imágenes en el Notebook de Júpiter
options(repr.plot.height = 3.5) #Esto solo es para hacer más pequeñas las imágenes en el Notebook de Júpiter

# Crearemos el mismo gráfico obtenido con la función plot(), personalizando colores
ggplot(data.frame(x=c(0, 11)), aes(x)) + 
    stat_function(fun=function(x) (exp(-x)*sin(2*x + 3)), aes(ymin=0,ymax=..y..),
        geom = 'ribbon', fill = '#7a92a4', color = 'blue', alpha = 0.3) +
    labs(x = 'x', y = expression(paste(f(x),'=', e^-x*sin(2*x + 3)))) + 
    theme_linedraw()

References