-R es un lenguaje de computación técnica que trabaja en un ambiente basado en objetos. Algo similar a lenguajes previos como son MATLAB (Octave), Python o S. El mismo surge como una alternativa de fuente abierta al lenguaje de programación S desarrollado por uno de sus credores mientras trabajaba en los laboratorios Bell. Posteriormente, se desarrolló el lenguaje en la Universidad de Auckland, Nueva Zelanda por Ross Ihaka, Robert Gentleman y John Chambers (el creador de S). Derivado de esto, R
se ha convertido en un referente y, junto con Python es el lenguaje de programación técnica más utilizado en la ciencia y la práctica profesional.
Gracias a la flexibilidad para crear programas, existe una pléyade de paqueterías o librerías que contienen funciones o programas, mismos que pueden llamarse al ambiente de trabajo y ejecutarse por medio de sintaxis o líneas de comandos. Veamos un ejemplo de una línea de comando (Nota: el signo #
sirve para poner texto o notas que no se evaluarán por parte de R):
# Se carga la librería ggplot2 para gráficas (ya instalada si corrió todas las instrucciones de instalación de R)
library(ggplot2)
# Creación de datos simulados:
x1=rnorm(250,0,1)
x2=rnorm(250,0,12)
# Creación de vector X con número de observación:
t=seq(1:250)
#Creación de la gr´fica con los comandos ggplot:
p1=ggplot()+geom_line(aes(x=t,y=x1),colour="red")+geom_line(aes(x=t,y=x2),colour="blue")+
xlab("tiempo")+ylab("valor simulado")
# presentación de la gráfica en pantalla:
p1
Ejemplo inicial de una serie de comandos
En el ejemplo anterior, se generaron dos muestraso series de tiempo de datos denominadas X1
y X2
que, respectivamente, tienen 250 datos generados aleatoriamente pormedio de una función normal o gaussiana. el comando library(ggplot2)
está invocando una paquetería de gráficas llamada ggplot2
la cual es gratuita y,una vez instalada en la computadora, puede ejecutarse en comandos como en de la quinta y sexta línea.
Como se puede apreciar, se crearon, con una serie de comandos como rnorm
objetos que tienen valores numéricos (numeric
) u objetos tipo ggplot como p1
que, al ser llamados, generan la figura @ref(fig:fig1).
Ventajas: 1. Es fuente abierta. 2. Permite la integración de múltiples paqueterías o librerías para desarrollar cálculos y trabajos de investigación 3. Permite integración con servicios de bases de datos externas como las de INEGI, Banxico, QUANDL, FMI, Bloomberg, etc. 4. Permite la integración con manejadores de bases de datos como MySQL o SQLlite para el procesamiento de grandes cantidades de datos. 5. Permite la integración de otros lenguajes de programación como C++, Java, MATLAB o Python. 6. Permite la lectura de archivos de otros softwares estadísticos como son Eviews, SPSS, STATA o S-plus. 7. Es un ambiente basado en objetos y permite la generación de tablas y gráficas de salida para ser exportadas en múltiples formatos como son excel, word, power point, *.csv
, *.txt
,
Desventajas: 1. La plataforma original R
es muy robusta pero tiene una interfaz visual pobre. 2. Al momento de generarse algún tipo de error de programación, el motor de R
no apoya a la usuario o usuario en señalar el posible error. 3. La atención de errores no existe de manera directa (al ser un software de fuente abierta) y se hace por medio de blogs o sitios web.
A pesar de las tres limitaciones previas, estas pueden reducirse drásticamente al emplear la interfaz de usuario Rstudio. Con la misma se pueden revisar tablas de datos o los objetos de una manera más amigable, se pueden generar sitiow web (como este), artículos de investigación, tesis de grado, reportes científicos, presentaciones e incluso aplicaciones en línea.
El mismo puede correrse en una computadora en su versión desktop o en línea si se cuenta con un servidor y el software Rstudio server instalado en el mismo. Esto último es muy útil en universidades, facultades o lugares de trabajo que requieran múltiples usuarios para programar y que deseen realizar su trabajo a distancia. Tanto R como Rstudio server también pueden ser instalados en clústers de súper cómputo como los de las universidades o incluso en capacidades en renta como son los servidores o clústers de Google, Amazon, Azure-Microsoft, IBM o afines. Esto permitiría a investigadores el poder procesar cálculos complejos y largos en infraestructura rentada.
El presente curso estará enfocado primordialmente a programar en Rstudio, teniendo como motor de procesamiento el R original. Es decir El R original seguirá siendo el motor de procesamiento de fondo y el Rstudio el IDE o interfaz con el usuario.
A pesar de las múltiples ventajas que Rstudio presenta (de las cuales solo investigaremos algunas pocas), el mismo tiene una limitante de capacidad a considerar Cuando se trabajan con bases de datos muy grandes o tablas con muchos registros, el mismo puede ser inestable y atorarse, al ser una interfaz visual. Sin embarogo, el procesamiento de grandes cantidades de datos por medio de Rstudio puede ser compensado al tener la citada base de datos gigante en un procesador de bases de datos como MySQL y su interfas o IDE MySQL workbench, los cuales pueden integrar muy bien con Rstudio.
Esto último no se verá a detalle en este curso (al ser introductorio) pero se menciona para el conocimiento general. Antes de entrar a la programación en R por medio de Rstudio, es importante hacer un paréntesis para hacer algunos comentarios de instalación de necesidad previa.
Algo que esmuy importante conocer, son los pasos y requerimientos necesarios para tener instalado R y Rstudio en la computadora. Esto cambia entre computadoras con sistema operativo Windows y computadoras con OS de Mac. Veamos para cada caso.
Para instalar R, es necesario descargar el instalador del lenguaje R. Este debe ser la versión 3.4.4 ya que la 3.5.0, al momento de actualizar estas instrucciones, tiene una serie de inestabilidades y problemas en algunas librerías. Para descargar el instalador para sistema operativo Windows, presione esta liga. Para descargar el instalador para sistema operaticvo iOs de Mac, presione esta liga (recuerde que es la versión 3.4.4 la necesaria).
Una vez descargado, por favor instálelo. La instalación en Mac requiere de algunos ajustes adicionales. por favor, consúltelos en la sección de “Instrucciones adicionales de la instalación de R para usuarios de Mac” siguiente.
De manera complementaria, será necesario descargar el paquete instalador de LaTex. Para usuarios con Windows , es necesario instalar MikTex y de todas sus librerías para windows. Esto puede hacerlo en esta liga. Para usuarios con iOS de Mac, es necesario descargar MacTex en esta liga.
Una vez descargado, por favor instálelo e inícielo por primera vez. De manera complementaria, por favor inicie R por primera vez. Deberá ver una pantalla como esta:
Una vez que corra tanto R como las intstalación de Latex (Miktex o MactTex), se le pide descargar Rstudio Preview desde esta liga (la liga aplica para cualquier sistema operativo). Una vez que lo tenga, por favor instálelo. NOTA: Se sugiere primero instalar debida y completamente R i Latex.
Una vez instalado, abrir Rstudio. Con esto severá una ventana como esta:
Por favor descargue el siguiente archivo de esta liga. Regrese, por favor, a Rstudio y presione la siguiente selección de menús: File > Open File y seleccione el archivo instaladorrstudio.R
que descargó. Ahora lucirá así la ventana de Rstudio:
Por favor, una vez abierto el script de R córralo presionando el menú source
a la derecha (como se marca en la elipse naranja) y seleccione la opción source
de nuevo como se marca con la flecha. Con esto, la secuencia de comandos para instalar algunar librerías esenciales correrá. Al ir detectando el programa que estas no están instaladas, las descargará del servidor CRan de R y las instalará automáticamente. Cuando aparezca el mensaje “Actualizacion de paqueterias completado”, habrá concluido el proceso de isntalación exitosamente y su Rstudio y R estarán listos para trabajar.
Nota: Recuerde que Miktex o MacTex deben estar instalados y debe haberlos abierto por primera vez.
Para poder instalar R en su MAC, hay una serie de pasos que le sugiero realizar antes de instalar Rstudio y correrlo. De lo contrario no correrá adecuadamente ya que R, según el compilador que puede descargarse requiere el código de programación propio de Mac-OS (Xcode), que es el símil de Visual basic en Windows.
Los pasos a seguir son:
Entrar a app store desde su computadora y descargar la versión más reciente de Xcode para desarrolladores. Son alrededor de 2 GB de tamaño de archivo a descargar. Una vez instalado desde app store, debe buscar en la carpeta “aplicaciones” el ícono y correr el programa. Si nunca a corrido el mismo, le pedirá aceptar la licencia y condiciones de uso para funcionar. Deberá hacerlo para activar el mismo y hacerlo funcionar correctamente en su computadora.
Descargar el instalador de X Windows para Mac en esta liga. posteriormente,instálelo y ejecútelo.
Reiniciar su ordenador.
Correr Rstudio.
Una vez que se ha descrito brevemente la instalación y algunas cuestiones generales de Rstudio, iniciemos con la manipulación de objetos y los tipos de los mismos.
Como se describió previamente, R (y Rstudio como su interfaz visual) es un lenguaje de programación en un ambiente de trabajo por objetos. Para las usuarias o usuarios relacionados con otras paqueterías como Stata, Eviews o SPSS, esto es algo natural ya que se crean diferentes objetos de diferentes tipos,mismos que se manipulas en cálculos o análisis.
Para ilustrar la idea previa, se describirán los diferentes tipos básicos de objetos que se manejan en R, así como la generación de los mismos. Veamos el caso más básico de estos. A continuación se va a generar un objeto llamado objetoA
que será un vector fila u horizontal de números 1,2,3,4 y 5. Estose puede hacer en la ventana de la consola (console) que se encuentra en Rstudio como se aprecia en la siguiente imagen:
# Se crea el objeto llamado objetoA:
objetoA=c(1,2,3,4,5)
Como se puede apreciar a la derecha de Rstudio, en la pestaña Environment, se creó un objeto titulado objetoA
en donde se señala que es un objeto tipo num
y donde se muestran los valores siguientes:
Algo que esde mucha importancia tener presente es el hecho de que las mayúsculas y minúsculas en los nombres de los objetos y comandos son importantes. Si escribimor en la consola OBJETOA
, se está invocando un objeto que, en términos semánticos es igual al que se acaba de crear pero que es diferente en realidad. si se escribe OBJETOA
en la consola se tendráel siguiente mensaje: Error: object 'OBJETOA' not found
. Esto significa que, en el ambiente de trabajo no existe algún objeto que se llame así. Ahora si creamos el siguiente OBJETOA
se generará un nuevo objeto como se aprecia. Esto con el comando c( )
:
# Se crea el objeto llamado objetoA:
OBJETOA=c("uno","dos","tres","cuatro","cinco")
OBJETOA
## [1] "uno" "dos" "tres" "cuatro" "cinco"
Ahora se puede apreciar en el espacio de trabajo (workspace) que hay dos objetos diferentes. objetoA
es un objeto de tipo numérico y OBJETOA
es uno de tipo caracter o character
(chr
) compuesto de elementos de texto. Para verificar qué clase o tipo de objeto se tiene, se puede utilizar el comando class
:
class(objetoA)
## [1] "numeric"
class(OBJETOA)
## [1] "character"
Una operación de mucha utilidad es la indización de los objetos creados. Es decir, seleccionar objetos dentro de un objeto para manipularlos o crear otros. Para ejemplificar esto, se va a generar un objeto llamado indizado
que tendrá los números (y textos) 1 y 3 de los objetos objetoA
y OBJETOA
de manera intercalada. Veamos:
indizado=c(objetoA[1],OBJETOA[1],objetoA[3],OBJETOA[3])
indizado
## [1] "1" "uno" "3" "tres"
Como se puede apreciar, se generó el nuevo objeto indizado
en el ambiente de trabajo, el cual tiene elementos tanto de texto como de número. Algo muy importante a tener presente es cómo se indiza. Al igual que MATLAB
, R
manipulasa la mayoría de los objetos como vectores o matrices. En el caso particular de objetoA
y OBJETOA
se tiene el caso de dos vectores filas de dimensión \(1\times5\). Es decir, tiene una fila y cinco columnas. Por lo tanto, al escribir objetoA[1]
estamos pidiendo a R que extraiga el valor de la primera fila de dicho objeto (1). Cuando se escribe OBJETOA[3]
, se extraeel valor “tres”, cuando se emplea el comando c()
se concatenan o acomodad (enlazan) estos elementos en un solo vector.
Veamos ahora el caso de una matriz. Generamos una con valores concatenados:
matriz=rbind(c(1,2,3),c(4,5,6),c(7,8,9))
matriz
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 4 5 6
## [3,] 7 8 9
Como se aprecia, el objeto generado es una matriz de dimensión \(3\times3\) con los números 1 al 9 acomodados en cada fila en el ordenado por las tres columnas. Aquí surge un nuevo comando llamado rbind()
que sirve para enlazar o concatenar filar, siendo el comando cbind
un comando empleado para concatenar columnas:
matrizota=cbind(matriz,matriz)
matrizota
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 1 2 3 1 2 3
## [2,] 4 5 6 4 5 6
## [3,] 7 8 9 7 8 9
El objeto matrizota
no es mas que la concatenación por columnas del objeto matriz
consigo mismo. Algo muy importante a tener presente con los comandos cbind()
y rbind()
es que la dimensión de las filas y columnas a concatenar debe ser la misma. Es decir, tener el mismo número de filas o columnas.
Ahora, veamos un ejemplo de cómo seleccionar un objeto de la matriz matrizota
. Esto al seleccionar el objeto de la fila 2 y columna 3 (6):
seleccion1=matrizota[2,3]
seleccion1
## [1] 6
De manera similar, pueden seleccionarse rangos de filas y/o columnas (filas 2 a 3 y columnas 3 a 5):
seleccion2=matrizota[2:3,3:5]
seleccion2
## [,1] [,2] [,3]
## [1,] 6 4 5
## [2,] 9 7 8
También pueden seleccionarse números de filas y columnas según un orden plantead por la o el analista. Ahora seleccionaremos objetos de las filas 3,1,2 (en ese orden) con valores de las columnas 2,2,1,3 (en ese orden también):
seleccion3=matrizota[c(3,1,2),c(2,2,1,3)]
seleccion3
## [,1] [,2] [,3] [,4]
## [1,] 8 8 7 9
## [2,] 2 2 1 3
## [3,] 5 5 4 6
Por último, también pueden seleccionarse filas o columnas completas con solo dejando un espacio. Veamos para seleccionar una fila completa en donde queremos seleccionar todas las filas de la columna 2 del objeto matrizota
.Como se aprecia, simplemente sedeja sin valor el número de filas (antes de la coma) para llegar a esta instrucción matrizota[,2]
:
seleccion4=matrizota[,2]
seleccion4
## [1] 2 5 8
Ahora veamos qué hacer si queremos seleccionar todas las columnas de una fila. Por ejemplo, todas las observaciones de la fila 3 del objeto matrizota
:
seleccion5=matrizota[3,]
seleccion5
## [1] 7 8 9 7 8 9
Esta operación de indización es de mucha utilidad junto con el método de indización de objetos tipo data.frame
que veremos en la seccion correspondiente.
Para determinar el número de elementos de un objeto numeric, se pueden utilizar dos posibles comandos. El comando length()
solo sirve para vectores numéricos o de tipo character. Es decir, solo sirve para vectores y el comando dim()
que sirve para matrices y tablas u objetos data.frame. Veamos dos ejemplos. El primero para el objeto (vector) seleccion5
y el segundo para el objeto matrizota
:
length(seleccion5) # Tamaño del vector "a"
## [1] 6
dim(matrizota) # Dimensiones de la matriz "matrizota"
## [1] 3 6
Para el caso del vector, nos indica que el mismo tiene 3 elementos y, en el caso de matrizota, nos dice que tiene 3 filas y seis columnas respectivamente.
En algunas ocasiones se desea asignar un nombre a cada número u observación de un objeto numérico. Veamos un ejemplo para ilustrar:
numericnames=c(obj1=1,obj2=rnorm(1,0,1),obj3=17.32,obj4=pi)
numericnames
## obj1 obj2 obj3 obj4
## 1.00000000 0.04550442 17.32000000 3.14159265
Esto es de ayuda si, por cuestiones del análisis, deseainvocarse algún elemento del vector por su nombre y no por su número de fila o columna. Veamos:
numericnames["obj3"]
## obj3
## 17.32
Una forma alternativa de seleccionar columnas es por medio de indicadores lógicos en los que debe cumplirse alguna condición de igual ("=="
), mayor o igual (">="
), menor o igual ("<="
), mayor (">"
) o menor ("<"
). Veamos ejemplos:
matrizota[which(matrizota[,1]>2),1]
## [1] 4 7
Aquí lo que se pide es seleccionar todas aquellas filas (de la columna 1 que se solicita después de la coma) que cumplan con tener un valor mayor a 2. Esto se logra con el comando which
en el que se especifica una selección basada en aquellas entradas que sean TRUE
o ciertas en este requisito. Veamos:
matrizota[,1]>2
## [1] FALSE TRUE TRUE
Al ser la seguna y tercera filas TRUE
, el comando which
determinarlos números de fila en TRUE
así:
which(matrizota[,1]>2)
## [1] 2 3
Por tanto, se llega a seleccionar las filas 2 y 3 de la columna 1 del objeto matrizota
.
Otra operación de utilidad es el tener la posibilidad de eliminar elementos del vector o matriz. Esto se logra al poner el signo menos (-
) antes de los elementos a eliminar. Para ilustrar la idea, primero crearemos un objeto que sea una secuencia de números del -5 al 5:
secuencia=seq(-5,5,by=1)
secuencia
## [1] -5 -4 -3 -2 -1 0 1 2 3 4 5
El comando seq()
es de amplia utilidad para crear números consecutivos y, dentro de sun principales insumos o inputs esta seq([número inicial],[número final],by=[el incremento entre números dentro de la secuencia])
. Como nota de dedo, se tiene que el incremento entre números puede ser de 1 en 1 (by=1
), d e0.1 en 0.1 (by=0.1
), de 38 en 38 (by=38
), o en incrementos discretos.
Ahora, supóngase que se desean eliminar delobjeto los números -4 y 2 que son los elementos 2 y 8 en el vector. Esto se logra de la siguiente manera:
secuencia=secuencia[c(-2,-8)]
secuencia
## [1] -5 -3 -2 -1 0 1 3 4 5
Vemos en el resultado que se eliminaron los números buscados.
Ahora veamos las principales operaciones que se pueden hacer con objetos numeric. Comencemos por la suma. Para esto, crearemos dos objetos llamados a=(1,2,3)
y b=(2,2,2)
. Luego los sumaremos para crear un objeto llamado c1
:
# Se crean los vectores:
a=c(1,2,3)
b=c(2,2,2)
# se suma:
c1=a+b
c1
## [1] 3 4 5
Ahora veamos la resta:
# Se crean los vectores:
a=c(1,2,3)
b=c(2,2,2)
# se suma:
c2=a-b
c2
## [1] -1 0 1
¿se pueden sumar vectores de diferentes dimensiones? NO Esto tanto para la suma convencional como matricial.
Ahora veamos qué sucede con matrices. Podemos hacer esta suma:
\[\left[ \begin{matrix} -1 & 3 \\ 2 & -4 \end{matrix} \right]+\left[ \begin{matrix} 2 & 2 \\ 2 & 2 \end{matrix} \right]=\mathbf{A}+\mathbf{B}=\mathbf{C}\]
# Se crean los vectores:
A=matrix(c(1,3,2,-4),nrow=2,ncol=2)
B=matrix(c(2,2,2,2),nrow=2,ncol=2)
C=A+B
C
## [,1] [,2]
## [1,] 3 4
## [2,] 5 -2
Hasta ahora hemos visto las principales operaciones con objetos tipo numeric. Existen otras más pero estas son pripias de análisis más amplios que salen de la óptica de este curso introductorio. Procedamos, entonces, a revisarotro tipo de objetos.
Una forma muy útil de trabajar con objetos numéricos y de texto (character) es el comando paste()
.El mismo ayuda a generar anuncios o cadenas de text y números a partir de objetos. Veamos un simple ejemplo:
texto="Este es el ejemplo número "
mm=1
paste(texto,mm," del comando paste",sep="")
## [1] "Este es el ejemplo número 1 del comando paste"
Como se puede apreciar, el comando paste()
es el equivalente al comando concatenar de excel y permite concatenar los objetos, textos o números en el orden presentado, indicando el separador entre objetos. Para el caso de este primer ejemplo, se utilizó sep=""
para indicar queno hay separador. Sin embargo, se puede variar un separador de objetos como este sep=-+//
y se tendría el siguiente cambio:
texto="Este es el ejemplo número "
mm=1
paste(texto,mm," del comando paste",sep="-+//")
## [1] "Este es el ejemplo número -+//1-+// del comando paste"
Nótese ahora cómo los símbolos -+//
separan ahora el texto del objeto texto
, con el valor del objeto mm
y el texto agregado " del comando paste".
Este comando paste()
Será de utilidad para encabezados, textos de salida en las tablas de resultados o comandos como print()
para imprimir resultados en la pantala (consola)
Otro tipo de objeto de interés y mucha utilidad son los objetos tipo list
que no son más que objetos que tienen, dentro de si, colecciones de objetos. Para ilustrarlo con más exactitud, veamos un ejemplo:
list1=list(objeto1=matriz,objeto2=matrizota,sublista=list(sel1=seleccion1,sel2=seleccion2))
Si nos dirigimos al ambiente de trabajo a la derecha de Rstudio, veremos este nuevo objeto:
Si presionamos (damos click) dos veces, se abrirá una previsualización como esta:
Como se puede apreciar en el comando anterior, el comando list()
permite agrupar muchos objetos dentro de uno e incluso asignarles un nombre (que puede ser el mismo del objeto coleccionado o no). Por ejemplo list1=list(objeto1=matriz,objeto2=matrizota)
genera un nuevo objeto tipo list llamado list1
que tiene dos objetos llamados objeto1
que se crea con el objeto matriz
y un objeto2
que se crea con el objeto matrizota
o alguna otra instrucción o comando. A su vez,un objeto tipo list, puede tener listas dentro de si y estas “sub listas” pueden tener otras “sub listas”. Esto se ve con en la instrucción anterior como sigue: list1=list(...,sublista=list(sel1=seleccion1,sel2=seleccion2))
.
NOTA: Si queremos visualizar cualquier objeto en el amiente de trabajo, podemos dar doble click en el mismo o acudir a la consola insertando el siguiente comando: View([nombre del objeto a visualizar])
.
El juntar o agrupar objetos dentro de otros objetos, como el objeto list, va a permitir, como veremos en otros temas, la adecuada manipulación de datos paracálculos, así como la agrupación de resultados. Un ejemplo de esto se verá con el comando lm()
que es de utilidad y estándar para realizar regresiones lineales con el método de mínimos cuadrados ordinarios. El objeto de salida con dicha instrucción es, como se verá en su momento, un objeto tipo list, en donde se agrupan múltiples resultados de múltiples análisis.
Al igual que los objetos tipo numeric o character, los objetos list pueden ser indizados. Es decir pueden seleccionarse partes de los mismos. Por ejemplo, suponga Usted que el objeto list1
es resultado de salida en un cálculo que Usted programó en alguna instrucción o resulta del cálculo de alguna librería. Supongamos que queremos crear un objeto nuevo llamado objetonuevo
que resulta de multiplicar por 3 los valores de las columnas 2 a 5 de la fila 2 en el sub objeto objeto2
en list1
. Esta sería su instrucción en R:
objetonuevo=list1$objeto2[2,2:5]*3
objetonuevo
## [1] 15 18 12 15
Para indizar objetos dentro de una lista, debe emplearse el símbolo $
. Por ejemplo, list1$objeto2
pide a R estraer a la memoria RAM el objeto2
dentro de list1
. Posteriormente, en la misma instrucción, se aprecia la indización como si fuera un objeto tipo numeric o character [2,2:5]
. Esto es, del objeto en la memoria RAM se seleccioan la fila 2 y las columnas 2 a 5. por último, la computadora multiplica por 3 (list1$objeto2[2,2:5]*3
) los datos seleccionados y guarda el resultado en el objeto llamado objetonuevo
.
Este es quizá el objeto, para fines de análisis y presentación de resultados, más importante de todos ya que el mismo sirve para generar un objeto tipo tabla.Como todaslas tablas que en varias ocasiones usted habrá manipulado, la misma puede tener nombres de encabezados y de filas. Para exponer la idea introduzcamos en la consola el siguiente comando mtcars
. El mismo es una colección de datos que R
trae por defecto, el cual es una objeto tipo data.frame o tabka con datos de la revista Motor Tred en 1974. La misma resume algunos aspectos de desempeño o diseño de 32 automóviles del año1:
library(kableExtra)
## Warning: package 'kableExtra' was built under R version 3.4.4
kable(mtcars)
mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | |
---|---|---|---|---|---|---|---|---|---|---|---|
Mazda RX4 | 21.0 | 6 | 160.0 | 110 | 3.90 | 2.620 | 16.46 | 0 | 1 | 4 | 4 |
Mazda RX4 Wag | 21.0 | 6 | 160.0 | 110 | 3.90 | 2.875 | 17.02 | 0 | 1 | 4 | 4 |
Datsun 710 | 22.8 | 4 | 108.0 | 93 | 3.85 | 2.320 | 18.61 | 1 | 1 | 4 | 1 |
Hornet 4 Drive | 21.4 | 6 | 258.0 | 110 | 3.08 | 3.215 | 19.44 | 1 | 0 | 3 | 1 |
Hornet Sportabout | 18.7 | 8 | 360.0 | 175 | 3.15 | 3.440 | 17.02 | 0 | 0 | 3 | 2 |
Valiant | 18.1 | 6 | 225.0 | 105 | 2.76 | 3.460 | 20.22 | 1 | 0 | 3 | 1 |
Duster 360 | 14.3 | 8 | 360.0 | 245 | 3.21 | 3.570 | 15.84 | 0 | 0 | 3 | 4 |
Merc 240D | 24.4 | 4 | 146.7 | 62 | 3.69 | 3.190 | 20.00 | 1 | 0 | 4 | 2 |
Merc 230 | 22.8 | 4 | 140.8 | 95 | 3.92 | 3.150 | 22.90 | 1 | 0 | 4 | 2 |
Merc 280 | 19.2 | 6 | 167.6 | 123 | 3.92 | 3.440 | 18.30 | 1 | 0 | 4 | 4 |
Merc 280C | 17.8 | 6 | 167.6 | 123 | 3.92 | 3.440 | 18.90 | 1 | 0 | 4 | 4 |
Merc 450SE | 16.4 | 8 | 275.8 | 180 | 3.07 | 4.070 | 17.40 | 0 | 0 | 3 | 3 |
Merc 450SL | 17.3 | 8 | 275.8 | 180 | 3.07 | 3.730 | 17.60 | 0 | 0 | 3 | 3 |
Merc 450SLC | 15.2 | 8 | 275.8 | 180 | 3.07 | 3.780 | 18.00 | 0 | 0 | 3 | 3 |
Cadillac Fleetwood | 10.4 | 8 | 472.0 | 205 | 2.93 | 5.250 | 17.98 | 0 | 0 | 3 | 4 |
Lincoln Continental | 10.4 | 8 | 460.0 | 215 | 3.00 | 5.424 | 17.82 | 0 | 0 | 3 | 4 |
Chrysler Imperial | 14.7 | 8 | 440.0 | 230 | 3.23 | 5.345 | 17.42 | 0 | 0 | 3 | 4 |
Fiat 128 | 32.4 | 4 | 78.7 | 66 | 4.08 | 2.200 | 19.47 | 1 | 1 | 4 | 1 |
Honda Civic | 30.4 | 4 | 75.7 | 52 | 4.93 | 1.615 | 18.52 | 1 | 1 | 4 | 2 |
Toyota Corolla | 33.9 | 4 | 71.1 | 65 | 4.22 | 1.835 | 19.90 | 1 | 1 | 4 | 1 |
Toyota Corona | 21.5 | 4 | 120.1 | 97 | 3.70 | 2.465 | 20.01 | 1 | 0 | 3 | 1 |
Dodge Challenger | 15.5 | 8 | 318.0 | 150 | 2.76 | 3.520 | 16.87 | 0 | 0 | 3 | 2 |
AMC Javelin | 15.2 | 8 | 304.0 | 150 | 3.15 | 3.435 | 17.30 | 0 | 0 | 3 | 2 |
Camaro Z28 | 13.3 | 8 | 350.0 | 245 | 3.73 | 3.840 | 15.41 | 0 | 0 | 3 | 4 |
Pontiac Firebird | 19.2 | 8 | 400.0 | 175 | 3.08 | 3.845 | 17.05 | 0 | 0 | 3 | 2 |
Fiat X1-9 | 27.3 | 4 | 79.0 | 66 | 4.08 | 1.935 | 18.90 | 1 | 1 | 4 | 1 |
Porsche 914-2 | 26.0 | 4 | 120.3 | 91 | 4.43 | 2.140 | 16.70 | 0 | 1 | 5 | 2 |
Lotus Europa | 30.4 | 4 | 95.1 | 113 | 3.77 | 1.513 | 16.90 | 1 | 1 | 5 | 2 |
Ford Pantera L | 15.8 | 8 | 351.0 | 264 | 4.22 | 3.170 | 14.50 | 0 | 1 | 5 | 4 |
Ferrari Dino | 19.7 | 6 | 145.0 | 175 | 3.62 | 2.770 | 15.50 | 0 | 1 | 5 | 6 |
Maserati Bora | 15.0 | 8 | 301.0 | 335 | 3.54 | 3.570 | 14.60 | 0 | 1 | 5 | 8 |
Volvo 142E | 21.4 | 4 | 121.0 | 109 | 4.11 | 2.780 | 18.60 | 1 | 1 | 4 | 2 |
Si Usted corre la siguiente instrucción en la consola class(mtcars)
le dirá que es un objeto tipo data.frame. Si Usted corre la instrucción View(mtcars)
en la consola, podrá abrir la tabla en su ambiente de trabajo y analizar los datos con detalle.
Ahora hagamos un ejemplo en donde creamos una tabla u objeto data.frame a partir de objetos existentes como es el objeto matriz
. Esto se logra con la instrucción as.data.frame()
como se muestra a continuación:
tabladatos=as.data.frame(matriz)
tabladatos
Como se puede apreciar, el nuevo objeto tabla tiene los nombres de columna V1
, V2
y V3
, los cuales R asigna por defecto (significando Vector 1, Vector 2, Vector 3, recuerde que una tabla es una matriz y una matriz puede ser vectores fila o columna, como este caso, concatenados). En breve en la sección Cambio o manipulación de nombres de filas o de columnas en objetos data.frame veremos cómo manipular los nombres de las columnas y de las filas a nuestro gusto.
Una forma alternativa de crear tabla u objetos data.frame es haciéndola de cálculos existentes o de la “nada”. Esto es, sin tener que transformar una matriz u objeto existente. Para ilustrar con menos palabras y más claridad, veamos el siguiente ejemplo:
tabladatos2=data.frame(objeto1=c(1,2,3,4), # Se crea columna "sujeto 1" y se especifican sus datos
objeto2=c(rnorm(4,0,1)), # Se crea columna "sujeto 2" y se especifican sus datos
objeto3=c(rnorm(4,0,2)), # Se crea columna "sujeto 3" y se especifican sus datos
# Si así se desea, se pueden personalizar los nombres de cada fila como se muestra:
row.names=c("observación 1","observación 2","observación 3","observación 4"))
# Se presenta la tabla creada:
tabladatos2
Como se aprecia, se pueden ir creando los nombres de cada columna y presentar los datos de ese objeto de estudio.
NOTA1: es muy importante que el tamaño de los vectores sea el mismo De los contrario sucedería esto (se cambió arbitrariamente el número de elementos del objeto 3 de 4 a 3 elementos):
tabladatos2B=data.frame(objeto1=c(1,2,3,4), # Se crea columna "sujeto 1" y se especifican sus datos
objeto2=c(rnorm(4,0,1)), # Se crea columna "sujeto 2" y se especifican sus datos
objeto3=c(rnorm(3,0,2)), # ---AQUÍ SE CAMBIÓ DE 4 A 3 LA CANTIDAD DE NÚMEROS GENERADOS---
# Si así se desea, se pueden personalizar los nombres de cada fila como se muestra:
row.names=c("observación 1","observación 2","observación 3","observación 4"))
# Se presenta la tabla creada:
tabladatos2B
Esto arrojaría el siguiente error: Error in data.frame(objeto1 = c(1, 2, 3, 4), objeto2 = c(rnorm(4, 0, 1)), : arguments imply differing number of rows: 4, 3.. Esto indica que el número de filas en cada columna de la tabla no es el mismo.
NOTA2: También es importante que, cuando se porporcionen los nombres de filas, el vector u objeto tipo character tenga el mísmo número de filas (en este caso 4). Veamos, si se quita “observación 4”:
tabladatos2B=data.frame(objeto1=c(1,2,3,4), # Se crea columna "sujeto 1" y se especifican sus datos
objeto2=c(rnorm(4,0,1)), # Se crea columna "sujeto 2" y se especifican sus datos
objeto3=c(rnorm(4,0,2)),
# ---AQUÍ SE CAMBIÓ DE 4 A 3 LA CANTIDAD DE FILAS---
row.names=c("observación 1","observación 2","observación 3"))
# Se presenta la tabla creada:
tabladatos2B
Marca este error Error in data.frame(objeto1 = c(1, 2, 3, 4), objeto2 = c(rnorm(4, 0, 1)), : arguments imply differing number of rows: 4, 3.
Veamos otro ejemplo pero ahora utilizando datos de objetos existentes:
tabladatos2C=data.frame(objeto1b=seleccion3[,4], # Se crea objeto 1 con la cuarta columna de selección 3
objeto2b=seleccion3[,1], # Se crea objeto 2 con la primera columna de selección 3
# Si así se desea, se pueden personalizar los nombres de cada fila como se muestra:
row.names=c("observación 1","observación 2","observación 3"))
# Se presenta la tabla creada:
tabladatos2C
Como puede apreciar, la tabla mtcars
tiene un nombre de columna y de fila ya determinado. El mismo puede cambiarse o crearse por medio de los comandos colnames()
para cambiar los nombres de columna o rownames()
para cambiar los nombres de fila. Veamos cómo cambiar los nombres de columna del objeto tabladatos
generado en la sección Transformación de objetos existentes en objetos tipo data.frame con comando as.data.frame():
colnames(tabladatos)=c("Muestra 1","Muestra 2","Muestra 3")
tabladatos
Como se puede apreciar, la insrucción colnames()
aplicada al objeto tabladatos
implica que, al mismo, se pondrán los nombres que se presentan en el vector formado con el comando c()
. NOTA: Al igual que en los casos de asignación de nombres de columnas y filas vistos en la sección Creación de objetos data.frame “de la nada”, manipulando resultados y objetos con comando data.frame(), el número de elementos del vector debe ser igual al número de columnas. En caso contrario, marcará el mismo error relativo al número de columnas v.s. el número de encabezados.
De manera análoga, se puede emplear el comando rownames
para asignar los nombres de fila a la tabla. Veamos, con el entendido de que el número de nombres debe ser igual al número de filas para funcionar:
rownames(tabladatos)=c("Obs. 1","Obs. 2","Obs. 3")
tabladatos
Ahora que hemos revisado los principales tipos de objetos y operaciones que, en un análisis estadístico se pueden atravesar de manera general, procedamos a ver un poco de programación por medio de scripts o códigos de secuencias.
Hasta el momento hemos dado instrucciones muy específicas y aisladas en la consola de R
. Sin embargo, en el día a día científico y académico, se requieren análisis amplios, complejos e incluso repetitivos en donde cambian los datos de entrada pero se esperan prácticamente los mismos formatos de salida (gráficas, tablas, reportes, etc.) con los nuevos datos resultantes de una serie de procedimientoso análisis también complejos. Esto se logra con la ayuda de archivos con extensión *.R
, en donde sepueden presentar todotipo de instrucciones a ejecutar.
Para abrir un nuevo script, se siguen las siguientes instrucciones:
Apertura de nuevo sript de R
Presionar File > Save As… y darle un nombre de archivo al gusto.
Presionar File > Save with Encoding… y seleccionar el formato UTF-8. Esto esimportante por si,en sus títulos de tabla o figuras desea tener acentos o tildes en español.
Ya que tiene su archivo *.R
creado y guardado, comencemos revisando algunos de los principales operadores computacionales que nos serán de utilidad.
El comando for
, mejor conocido como ciclo o buckle sirve para repetir una cantidad de \(n\) veces una serie de instrucciones. Para ilustrar su uso, tengamos el siguiente ejemplo: supóngase que usted tiene que correr la regresión del consumo de 30 países con su correspondiente PIB y quiere evaluar el nivel medio de explicación por medio del coeficiente \(R^2\). Esto le implicaría, en una paquetería como SPSS o Eviews, el correr 30 regresiones y copias los valores del \(R^2\) en una tabla de excel. Luego poner manualmente los encabezados y finalmente exportar a word la tabla. Si los datos de su muestra cambian, Usted tendrá que correr todo de nuevo. Por fortuna, con lenguajes como R, se programa la secuencia de pasos e instrucciones y se ejecuta para realizar los cálculos. En específico, aquí aprenderemos a hacer todo esto con el apoyo de Rstudi
y, sobre todo, Rmarkdown
. Antes de pasar al último, primero debemos de dominar un poco la programación. Comencemos con un simple ejemplo el cálculo de cuánto dinero (\(\text{VF}\)) tendríamos después de \(m=1,000\) periodos, si prestáramos \(\text{VA}=1.00\) a un año (\(n=1\)), al 100% de interés (\(i=100\%=1\)) y con esos \(m=1,000\) periodos de recomposición.
Esto, claro está, no requiere mayor ciencia ya que es una operación muy simple de matemáticas financieras:
\[\text{VF}=\text{VA}\cdot(1+(i/m))^m=1\cdot(1+(1/1,000))^{1,000}=2.716924\]
Sin embargo, aquí haremos un ejercicio computacional para llegar al mismo número y para tener una tabla de salida de datos, en donde se hicieron las \(m=1,000\) re composiciones hasta llegar al final. Esto implica tener la siguiente sintaxis:
# Valores iniciales del problema
i=1 # tasa de interés
m=1000 # Número de peridos de recomposición
n=1 # número de periodos anuales
VF=matrix(0,m,1)# Se crea un vector con puros ceros, como una matiriz de m cantidad de filas y 1 columna.
# Comando for en donde se emplea un contador o variable cuyo valor se incrementa en una unidad con cada iteración o ciclo. En este caso, los valores de n inician de 1 a m=1,000:
for (n in 1:m){
# Empleo de comando if para cambiar el valor de VA como 1 si se trata del primer periodo de recomposición (n<2) o su valos será el valor futuro del periodo de recomposición anterior al actual (n-1)
if (n<2){
VA=1 } else {
VA=VF[(n-1)]
}
VF[n]=VA*(1+(i/m))
}
#View(VF) # Comando View() para visualizar el vector creado
Como se puede apreciar, en esta intrucción se utilizan tanto la instrucción For como la instrucción if, else. Para el caso del comando for, siempre debe tenerse la siguiente esctrcutura general que se aprecia en el código anterior:
n
).{
en donde se inicia la secuencia de instrucciones repetitivas a realizar en cada ciclo o iteración.}
. (NOTA estos dos corchetes abiertos y cerrados son muy importantes).Para el comando if, else, siempre se tiene la siguiente estructura general:
n
) sea menor a 2.{
, poner las instrucciones a realizar cuando se cumple el condicional y cerrar con un corchete de llave derecho }
las mismas.}
, la palabra else
y otro especio para abrir un nuevo corchete de llave izquierdo {
.}
. NOTA: Favor de referirse al código anterior.En el caso del comando for anterior se tiene una condición de paro específica que es el número de peridos m
de recomposición. Sin embargo, hay ocsiones en las que se requieren cálculos o iteraciones de alta precisión en donde la computadora debe de repetir el ciclo de instrucciones no hasta llegar a las m
repetidas, sino hasta que se cumpleuna condición de paro específica. Para ilustrar mejor la idea, cambiemos un poco el ejemplo anterior y definamos el siguiente objeto:
\[\text{difiter}=\text{VF}_{n}-\text{VF}_{n-1}\]
Esto es, la diferencia entre el valor futuro (\(\text{VF}\)) de la interación actual \(n\) menos la del valor futuro de la iteración anterior (\(\text{VF}_{n-1}\)). Esto nos lleva a replantear un ciclo o buckle que calculará y calculará hasta que el valor de difiter
sea menor o igual a determinado valor. Por ejemplo, deternes el ciclo repetitivo de cálculos hasta que se logre \(\text{difiter}\leq1\text{E}^{-16}\). Veamos cómo quedaría:
# Valores iniciales del problema
VA=1
i=1 # tasa de interés anualizada
m=1 # número inicial de periodos de recomposición al año
VF0=1
# variable que controlará la condición de paro:
difiter=100000
paroen=1e-16
while (difiter>paroen){
VF2=VA*(1+(i/m))^m
difiter=VF2-VF0
VF0=VF2
m=m+1
}
print(paste("Valor final:",VF2," logrado después de ",m," iteraciones..."," y un valor de paro de ",paroen,"...",sep=""))
## [1] "Valor final:2.71827156005115 logrado después de 132362 iteraciones... y un valor de paro de 1e-16..."
Como se puede apreciar, se utilizo ahora el comando while y, entre paréntesis, se colocó la condición que debe cumplirse para que sigan realizando las repeticiones de los cómputos o cálculos. Cuando esta deje de cumplirse, las repeticiones del while se suspenderán. El objeto paroen
determina el número umbral para la condición de paro y se utilizó el objeto VF0
para especificar el valor futuro logrado en la iteración anterior. Por último, para fines de registro, se puso el contador m
para registrarel número de iteraciones realizadas.
Por otro lado, para diferenciar el objeto VF
del comando for
del objeto de este ejercicio, se utilizóel nombre VF2
para realizar los cálculos. En caso contrario, se sustituirían los valores del objeto anterior (que es un vector) con los del actual.
El comando ‘print()’ se utiliza para presentar en la consola de Rstudio o R algún texto o valor que se indique dentro de los paréntesis. En este caso, se presenta o imprime el texto logrado con el comando paste()
visto en la sección El comando paste().
Por último, se revisa el caso del operador switch
. Este es similar al operador if
, con la diferencia de que aplica para objetos tipo character. Veamos un ejemplo en donde le pedimos a R que ponga el mensaje “Ejecutaste opción 1” y nos de el valor de la constante \(\pi\) o el mensaje “Ejecutaste opción 2” y nos de el valor de la constante \(e\):
# Se puede poner "opcion 1" u "opcion2":
opcion="opcion 1"
# Ejemplo de switch:
switch (opcion,
"opcion 1"={
print(paste("Ejecutaste opción 1 y el valor de pi es:",pi,sep=""))
},
"opcion 2"={
print(paste("Ejecutaste opción 2 y el valor de 2 es:",exp(1),sep=""))
},
{print("No elegiste una opción de las permitidas")}
)
## [1] "Ejecutaste opción 1 y el valor de pi es:3.14159265358979"
Con esto, se tienen algunos de los principales comandos para hacer algunos análisis estadísticos generales por medio de scripts de R
, así como para poder presentar reportes adecuados con mucha calidad y análisis sofisticados y robustos.
Los scripts de R previamente descritos son herramientas muy poderosas de programación. Sin embargo, no son prácticos para hacer reportes más completos como puede ser las notas para estudiantes, tesis de grado, artículos de investigación científica, reportes técnicos o científicos.
A diferencia de un procesador de texto convencional como Word, Latex, Documents o afines, Rmarkdown es una alternativa que nos permite procesar documentos incluyendo directamente (o no) los comandos de r y las gráficas demanera automatizada.
Para dar una idea de la necesidad a resolver con Rmarkdown, suponga Usted que debe elaborarse un reporte cada determinado periodo y el mismo implica extraer datos de una fuente externa o algún archivo *.xlsx
, *.csv
o *.txt
. Posterior a ello, deben hacerse una serie de análisis y elaborar un reporte con tablas, comentarios y texto que puede cambiar en algunos valores. Por otro lado, en muchas ocasiones (Como estas notas), se requiere de la capacidad de poder realicar notas y rporte, incrustar códigos de R o simplemente correr instrucciones y análisis de R dentro del reporte. Esto sin tener que copiar, pegar y demás.
Para esto es que sirve el emplear archivos Rmarkdown.
Para comenzar a trabajar con unarchivo de este tipo, primero debemos tener instalado Rmarkdown en Rstudio. Esto se logra (en la versión de Rstudio para computadora local), con la siguiente instrucción: install.packages("Rmarkdown")
. Si se trabaja con la versión de nube, no se tendrá problema alguno ya que viene precargado.
Posteriormente, se debe acudir al ícono del círculo verde con la cruz blanca que se encuentra en la parte superior izquierda y seleccionar la creación de un Rmarkdown como se muestra en la figura:
Posteriormente, les pedirá el nombre del nuevo archivo y el autor. Se sugiere seleccionar “document” en las opciones de la izquierda y la opción “HTML” (el tener HTML es lo más recomendado, ya que permitirá compilar sitios web, archivos *.pdf o archivos de word).
Al seleccionar el tipo de archivo, se notará que se abre una ventana como la siguiente:
Se le sugiere guardar el trabajo en el disco para comenzar a trabajar. El archivo que se abre es un archivo de muestra que consta de tres partes:
Pedazos o chunks de código R
que funcionan como rscripts incrustados y evaluados dentro del documento. Estos se visualizan en gris y se inician con tres acentos graves, dos corchetes de llave la letra r
dentro de los corchetes y un espacio con el nombre del chunk2 (```{r [nombre de chunk]}
). Después se presenta todo el código e instrucciones a evaluar y, finalmente, se cierra el chunk con tres acentos graves ```
(vea los espacios grises en la figura anterior).
Espacio de código markdown para redactar el texto con el documento. En el mismo se presentan las notas, comentarios, escritos, etc. que forman parte del documento a elaborar.
NOTA: Es de importancia clave que el primer chunk o pedazo titulado rsetup
nunca se elimine ya que son preparativos del Rmarkdown. Incluso se pueden poner ahí los códigos que soliciten las librerías necesarias para trabajar. Esto con la gran ventaja de que dicho fragmento de código nunca aparecerá ya que tiene la instrucción include=FALSE
. Esto significa que no será incluido en el documento final.
Ahora veamos cómo trabajar tanto en la creación de chunks como en la elaboración del documento rmarkdown. Para ilustrar con un ejemplo, vamos a hacer un ejemplo sencilli en donde bajaremos datos del repositorio de información económica y financiera Quandl (en específico, la variación porcentual del PIB de EEUU y las economías latinoamericanas más grandes) y haremos una página web con el análisis estadístico de los datos.
De manera complementaria, se expondrá la forma de trabajar para compilar lo anterior en un documento *.pdf en un sub tema posterior.
Para crear sitios web con Rmarkdown, necesitamos trabajar con el preámbulo Yaml en donde especificaremos el tipo de documento de salida que queremos. En las siguientes pestañas, se presentan los temas subdivididos para su consulta.
El preámbulo Yaml es lo que, en la mayoría de los casos, se pone al inicio del archivo Rmarkdown entre los renglones con los tres guiones ---
. Veamos el ejemplo del Yaml creado para las presentes notas:
title: “Introducción a R y Rstudio para el análisis estadístico y generación de reportes académicos” author: “Dr. Oscar V. De la Torre Torres” date: “7/31/2019” output: html_document: toc: yes toc_depth: 3 toc_float: yes pdf_document: toc: yes toc_depth: 3 lang: es-ES fontsize: 10pt font: times new roman
El campo title
Debe llevar el título del documento a compilar, el cual es conocido ya para usted. Lo propio sucede en author
y date
. El siguiente parámetro de interés es output
. Uno de los beneficios de Rmarkdown es que permite, como se mencionó, tener múltiples formatos de salida, como puede ser una página web o documento HTML (html_document
). Para esto, es importante dejar la palabra output con los dos puntos y, en la siguiente línea poner el formato de salida con dos puntos y un tabulado.
En la siguiente línea tabulada se plantean algunos parámetros de formato (de entre muchos que puede haber) como son toc: yes
. Esto significa que se está solicitando que se incluya un índice de contenido. toc_depth: 3
significa que pedimos que se presenten los títulos y sub títulos hasta el nivel 3 de jerarquía y toc_lfloat: yes
(solo aplica para documentos HTML) que significa que se está solicitando que el índice sea flotante o se mueva conforme navegamos en la página.
Para el caso de documentos *.pdf, sesigue la misma regla de tabulados que html_document, solo que no se incluye la instrucción que,como mencionamos previamente, solo aplica a documentos HTML.
Por último se establecen algunas indicaciones generales de los dos tipos de documento como son el lenguaje (lang: es-ES
español de España), el tamaño de la letra (fontsize: 10pt
) y la fuente que se utilizará en todo el documento (font: times new roman
)
Existen muchas más confugiraciones que se pueden agregar pero aquí veremos las más significativas. Para mayor referencia, foavor de revisar esta liga con más ejemplos y casos.
La forma de trabajar textos es relativamente sencilla. La primera forma consiste en presentar títulos y sub títulos. Si se escribe # Título 1
se está poniendo el título principal de una sección. Si se desea insertar un sub título a nivel dos se escribiría esto: ## Sub título 1.1
, para otro sub título de menor nivel: ### Sub título 1.1.1
y así sucesivamente #### Sub título 1.1.1.1
Si se dedea tener texto en itálica se escribe el texto en itálica como sigue: *texto en itálica*
. Si se quiere en negrita, se utilizan dos asteriscos: **texto en negrita**
. Negritas e itálizas es algo que no se puede hacer aquí. Tampoco la letra subrayada.
Si se desean conocer algunos aspectos adicionales de cómo trabajar con texto, se puede consultar esta hoja de trampa o cheat sheet. Ahí puede consultar algunas cuestiones adicionales como el poner elementos numerados, en viñetas o adicionales como tablas hechas “manualmente”.
Los pedazos de código de R
se pueden incorporar previamente como se dijo. Esto es, iniciando con ```{r [nombre de código]} y cerrándolo con ``` después de la última línea de código.
Existen varias configuraciones que pueden ser de interés como
```{r [nombre de código], eval=TRUE}. Si se emplea eval=TRUE
(opción por defecto) se está indicando que se quiere evaluar el código que se presenta. Si eval=FALSE
, se está pidiendo lo contrario.
```{r [nombre de código], echo=TRUE}. Si se emplea echo=TRUE
(opción por defecto) se está indicando que se quiere incluir el código que se presenta en el archivo HTML o *.pdf a compilar. Si eval=FALSE
, se está pidiendo lo contrario.
```{r [nombre de código], results=TRUE}. Si se emplea result=TRUE
(opción por defecto) se está indicando que se quiere se presenten los resultados de los cálculos del código en el documento a compilar. Si eval=FALSE
, se está pidiendo lo contrario.
Para mayores referencias de otras opciones de chunk, puede referirse a la hoja de trampa o cheat sheet previamente mencionada.
R
dentro del textoUna gran ventana de Rmarkdown es el hecho de que los valores de objetos que se han calculado en un chunk pueden ponerse en el texto del documento que se está generando. Por ejemplo:
“El PIB de México en el año 2017 tuvo una variación de 3%…”
En muchas ocasiones se requiere que enucniados anteriores se actualicen automáticamente en un reporte, conforme se actualizan los datos de insumo. Para ilustrar cómo actualizar el enunciado anterior, supóngase que se cuenta con un objeto llamado a.actual=2017 y otro objeto var.pibactual=0.03, los cuales se generaron y/o actualizaron al ejecutar algún o algunos chunks o pedazos de códigos. Esto llevaría a escribir, ya sobre el texto en el fragmento Rmarkdown, lo siguiente:
"El PIB de México en el año ` r a.actual ` tuvo una variación de ` r (var.pibactual)*100 `%…"
Como se puede apreciar, se mantiene prácticamente todo el texto en su forma original pero se agrega un fragmento de R
. Por ejemplo, en ` r a.actual ` se está pidiendo que se evalúe o imprima el valor de a.actual que es 2017. Con ` r (var.pibactual)*100 ` se pide que se evalúe el valor de var.pibactual y se multiplique por 100.
Cuando se trabaja con cifras en miles o millones, así como con decimales y se deseadar formato, se puede realizar alguna función de formato como formatC
, cuya sintaxis puede consultar en la sección FormatC para dar redondeo y formato, Así como las funciones de formato que puede consultar en la sección Algunos comandos o instrucciones de R de interés
A continuación se ponen algunas funciones (Dentre la pléyade de las mismas que existen) que pdorán serle de utilidad para compilar sus documentos o realizar cálculos:
Estas funciones sirven para redondear un número en determinada cantidad de dígitos, redondear hacia arriba, redondear hacia abajo o redondear hasta los dígitos significativos. Para ilustrar, pongamos el ejemplo del número \(\pi\) que se logra visualizar con el comando de R
pi
:
Esta función tiene solo dos insumos: el número a redondear (pi
en el ejemplo) y digits
o número de dígitos:
round(pi,digits=4)
## [1] 3.1416
Esta función tiene solo tiene el insumo del número a redondear:
floor(pi)
## [1] 3
Esta función tiene solo tiene el insumo del número a redondear:
ceiling(pi)
## [1] 4
Esta función tiene varios insumos más específicos y avanzados que se pueden consultar en esta liga. Sin embargo, aquí veremos, para el mismo número pi
multiplicado por 1000, en donde queremos que haya una coma para separar los miles:
formatC((pi*1000),format="f",digits=4,big.mark = ",")
## [1] "3,141.5927"
Ahora veamos el caso europeo en donde queremos un punto en los miles y una coma en los decimales
formatC((pi*1000),format="f",digits=4,big.mark = ".",decimal.mark = ",")
## [1] "3.141,5927"
El insumo format="f"
debe mantenerse siempre ya que en las ciencias administrativas (y parte de las económicas), siempre trabajamoscon números reales., el insumo digits
se utiliza para establecer el número de decimales a utilizar. Por otro lado, big.mark
sirve para definir qué símbolo se utilizará para marcar los miles y, decimal.mark
, hace lo propio para marcar los decimales.
Una de las ventajas de R o Rmardown, como interfaz visual, es que se puede extraer datos de proveedores externos como son sitios web, repositorios de bases de datos (como Quandl), INEGI, Banxico, bases de datos de proveedores de información de mercados financieros, el servicio meteorológico de la National Oceanic and Athmospheric Administration y otros. Para fines de ilustración que interesa en nuestro contexto, veremos el caso de Quandl
, el cual mencionamod en el apartado del tema Abriendo un archivo de Rmarkdown. Antes de analizar cómo extraemos dados de la base de datos, en específico los históricos de las variaciones porcentuales del PIB, es importante hablar un poco sobre la configuración previa que debemos hacer por primera y única vez. Esto,en el entendido de que será de utilidad para búsquedas futuras.
Quandl es, como ya se ha mencionado previamente, un repositorio de bases de datos de organismos y empresas que proveen información económica y financiera. El mismo es una colección de proveedores que, con un mismo usuario y contraseña, permite consultar en las mismas. Algunas de estas bases de datos son gratuitas como es el caso del Banco de Mexico, Fondo Monetario Internacional o Banco Mundial. Otras tienen el estatus de “premium” que implica que debe pagarse por obtener los datos. Pasemos a la configuración de nuestra cuenta y API Key
Primero se debe acceder al sitio web de Quandl en esta liga y acceder a la opción "sign up` como se muestra en la imagen
Se sugiere proporcionar sus datos y elegir la opción de uso “personal”. Después, al presionar el botón “next”, se deben llenar los datos de la contraseña a generar y sugiere seleccionar la opción de “I don’t know yet!” (no sé aún) para especificar el tipo de uso de la información. Por último, siga con el menú contextual y presiones “create account”.
Acto seguido le llegará a su correo electrónico (cheque en el spam o corre no deseado, porsi acaso). para confirmar la creación de la cuenta.
Ya con su cuenta creada, seleccione la opción “login” si no ve el ícono con el avatar que se señala en la imagen:
Si Usted visualiza dicho avatar, quiere decir que ya está registrada (o) como usuaria (o). por favor presione el avatar y dirígase a la opción “ACCOUNT SETTINGS” y, al abrir su perfil (profile) verá API KEY en el cuadro correspondiente. La misma se compone de múltiples letras, números y caracteres. Esta API key es de vital importancia tenerla y es personal (se puede regenerar si se la hackean con el botón “request new API key”). La misma se utilizará para que R
inicie una sesión en los servidores de Quandl y sea autorizado (es decir quelos servidores no identifiquen nuestra sesión de R
como un robot).
Ya una vez que se tiene la API key, procedemos a instalar la librería de Quandl si esta no está instalada en su computadora. Para ello se debe correr el siguiente comando en la consola de Rstudio: install.packages("Quandl")
. Deje que corra todo el proceso.
Una vez terminad, veamos cómo abrir una sesión en Quandl para nuestra computadora:
# Se invoca la librería Quandl al ambiente de trabajo. Esto una vez instalada:
library(Quandl)
# Se inicia la sesión con la API key lograda en Quandl
Quandl.api_key("Su API key va entre estas comillas")
Ahora que tenemos iniciada la sesión, es importante conocer las claves o identificadores de Quandl para los objetos o series de tiempo que queremos extraer. Para ello acudimos a Quandl y buscamos el siguiente campo de datos: Mexico GDP at constant price, % change
. Esto como se muestra en la imagen:
Se presiona enter y se seleccióna, de la base de datos del FMI (IMF Cross Country Macroeconomic Statistics
), la opción buscada. Esto como también se muestra en la imagen anterior. La selección realizada, nos llevará al sitio del indicador encontrado. En la parte superior derecha se encontrará un código o identificador de Quandl que será el que estamos necesitando para poder extraer este indicador a R
(véase la imagen siguiente para ubicarlo):
Ahora utilizaremos el comando Quandl
de la librería correspondiente para extraer no solo la variación porcentual del PIB mexicano, si no la de Argentina, Brasil, Chile, Colombia, Perú y Estados Unidos. Esto al consultar los quandl codes de cada uno y ponerlos juntos en un vector. Veamos:
# Se extraen los datos
Qdata = Quandl(c("ODA/ARG_NGDP_RPCH", # Quandl code de la Var. % del PIB de Argentina
"ODA/BRA_NGDP_RPCH", # Quandl code de la Var. % del PIB de Brasil
"ODA/CHL_NGDP_RPCH", # Quandl code de la Var. % del PIB de Chile
"ODA/COL_NGDP_RPCH", # Quandl code de la Var. % del PIB de Colombia
"ODA/MEX_NGDP_RPCH", # Quandl code de la Var. % del PIB de México
"ODA/PER_NGDP_RPCH", # Quandl code de la Var. % del PIB de Perú
"ODA/USA_NGDP_RPCH"), # Quandl code de la Var. % del PIB de EEUU
start_date="1990-12-31", # Fecha de inicio de la extracción de los datos
end_date="2018-12-31") # Fecha de fin de la extracción de los datos
# Aquí cambiamos los nombres de las columnas a unos más adecuados a nuestro análisis:
colnames(Qdata)=c("Fecha","Argentina","Brasil","Chile","Colombia","México","Perú","EEUU")
El comando Quandl
tiene varios insumos o inputs, siendo el primero de ello el texto entre comillas o el vector tipo character con el o los quandl codes de los campos de datos buscados. El segundo insuto start_date
corresponde a la fecha inicial de la búsqueda, cuyo formato siempre debe ser YYYY-mm-dd
. El segundo insumo es la fecha final o end_date
con el mismo formato.
Veamos el fragmento de tabla de las primeras 5 filas de los tres primeros paises del objeto Qdata:
Con esto vimos cómo es que se importan datos desde una fuente externa como Quandl. Veamos ahora el caso de cómo importar un archivo de excel.
Paraimportar datos desde un archivo de excel o *.xlsx
es necesario correr elcomando read.xlsx()
de la librería openxlsx
que se instala con el comando install.packages("openxlsx")
. Veamos un ejemplo para ilustrar: En la siguiente liga, Usted podrá descargar un archivo de excel de un ejercicio de la función Cobb-Douglas que encuentra en el libro de texto de Econometría de Gujarati. Por favor, descárguelo y póngalo en la misma carpeta en donde elaborará su archivo Rmarkdown.
library(openxlsx) # Se invoca la librería openxlsx
## Warning: package 'openxlsx' was built under R version 3.4.4
dataxls=read.xlsx("datos.xlsx") # Se extraen los datos desdeel archivo anexo con el comando
El ejemplo anterior es una forma muy simple de leer un archivo de excel al solo especificar el texto del nombre completo del archivo (en este caso datos.xlsx). Sin embargo, podemos leer el archivo desde una sub carpeta. Supóngase que se tiene una carpeta, llamada inputs, con archivos de excel, *.csv u otros y que adentro se encuentre el archivo datos.xlsx. La sintaxis para importar datos del archivo en esa carpeta sería dataxls=read.xlsx("inputs/datos.xlsx")
. Con esto, Rstudio busca dicha carpeta, la cual debe estar, a su vez, en la misma carpeta del archivo Rmarkdown elaborado.
Si deseamos leer un archivo separado por comas (*.csv), la sintaxis sería similar a la anterior y quedaría como sigue: dataxls=read.csv("datos.csv")
.
Hay algunos parámetros de lectura adicionales en la función que pueden ser de utilidad:
sheet
: El mismo sirve para especificar el nombre de hoja de cálculo a leer (ejemplo Hoja1). La sintaxis quedaría como dataxls=read.xlsx("datos.xlsx",sheet="Hoja1")
startRow
: Aquí se especifica cuál es la primer fila que debe leerse. Supóngase que los datos inician en la fila 3, con esto la sintaxis quedaría como dataxls=read.xlsx("datos.xlsx",sheet="Hoja1",startRow=3)
colNames
y/o rowNames
. Sus posibles valores son TRUE
o FALSE
para especificar si la primera columna o fila de lectura incluye los nombres de columnas o filas para el objeto data.frame.detectDates
. Sus posibles valores son también TRUE
o FALSE
y es una opción que detecta si hay alguna columna con fechas y lo convierte a un objeto tipo Date
. Este tipo de objetos son de necesidad para manipular o crear, en algunas ocasiones, gráficas.De la misma forma que se pueden importar datos desde un archivo de excel o *.csv, se pueden exportar objetos o tablas de datos en el mismo tipo de archivo. Veamos cómo sería la exportación para un archivo en excel.
Supóngase ahora que se desea escribir en un archivo de excel la tabla Qdata
que se generó y revisó en el sub apartado Ejecutando consultas de datos en Quandl. Para exportar se tiene esta sintaxis general (que podemos detallar con opciones similares al comando anterior):
write.xlsx(Qdata,"Datos_quandl.xlsx")
## Note: zip::zip() is deprecated, please use zip::zipr() instead
También se puede exportar el archivo no a la misma carpeta en donde se encuentra el archivo Rmarkdown con el que se está trabajando el análisis, sino a una sub carpeta (esta debe haber sido creada primero para poder correr el comando). Por ejemplo, supóngase que, en su misma carpeta donde el archivo de excel y el Rmarkdown están, se encuentra ua supcrpeta llamada “outputs”. El comando quedaría así: write.xlsx(Qdata,"output/Datos_quandl.xlsx")
.
Algunas otras opciones adicionales al comando y de interés pueden ser:
sheetName
: Es una cadena de texto donde podemos personalizar el nombre de la hoja de cálculo (write.xlsx(Qdata,"Datos_quandl.xlsx",sheetName="Datos salida")
).
gridLines
: Es una instrucción que especifica si queremos que los bordes de las celdas sevean o no. Si se deja la opción FALSE
, no se verán líneas divisorias de las celdas de Excel.
-tabColour
: Nos permite personalizar el color del separador que identifica la hoja de cálculo. Los valores de texto son colores en inglés factibles como “black”, “red”, “blue”, “orange” y otros permitidos. Si se desean conocer todos los nombres de las paletas disponibles en R
, se puede consultar la siguiente liga del documento elaborado por personal académico de la Universidad de Columbia.
zoom
: Este parámetro personaliza el zoom que, al abrir el archivo exportado, debe tener excel. Los valores posibles son de 10 a 400.
startCol
y/o startRow
: Son parámetros que indica qué fila y/o columna deben ser las primeras para escribir la tabla.
borders
: En esta opción se dice el tipo de
firstActiveRow
y/o firstActiveCol
: Si deseamos congelar filas para navegar en los datos de la hoja de cálculo, seespecifica cuál será la primera fila activa. esto en el entendido de que las anteriores permanecen congeladas. Por ejemplo, write.xlsx(Qdata,"Datos_quandl.xlsx",firstActiveRow=2)
deja congelada la primera fila de la hoja de cálculo. Lo propio sucede con la opción firstActiveCol
.
-colWidths
: En este se puede especificar solo la opción de "auto"
o NA
. La primera ajusta de manera automática los anchos de columnas y en la segunda, hace caso omiso a dicho ajuste.
Para mayor referencias de estas y otras opciones del comando write.xlsx()
, se puede consultar la siguiente liga de referencia. De manera análoga, se puede utilizar el comando csv.write()
. Para mayor referencia del mismo y cómo trabajar con sus parámetros u opciones, se puede consultar esta liga de referencia..
Ya se ha revisado cómo exportar tablas de datos a excel o a un archivo *.csv. Ahora se verá un ejercicio de cómo trabajar con objetos tipo lista que son propios de análisis de datos o librerías de análisis. El ejemplo más simple lo tenemos con el comando ‘lm()’ que sirve para correr un modelo de regresión. Para ilustrar el ejemplo, retomaremos el caso de los datos del PIB y correremos la siguiente ecuación de regresión:
\[\Delta\%\text{PIB}_{i,t}=\alpha+\beta\cdot \Delta\%PIB_{\text{EEUU}}+\varepsilon_t,\text{ }i:\text{iésimo país LATAM}\]
La idea del ejercicio es extraer el coeficiente \(\alpha\), \(\beta\), el error estándar de los residuales \(\sigma(\varepsilon_t)\) y el nivel de explicación o coeficiente \(R^2\). Esto en una misma tabla que podamos exportar a un archivo en excel y visualizar en este documento.
En construcción…
## Extraemos nombres de paises latinoamericanos:
paises=colnames(Qdata)
paises=paises[2:(length(paises)-1)]
# Paso 1: crear tabla de resultados yvector de conclusiones:
conclusion=matrix("-",length(paises),1)
colnames(conclusion)="Conclusión"
regtable=as.data.frame(matrix(0,length(paises),4))
colnames(regtable)=c("alpha","beta","err.est.modelo","R-cuad")
rownames(regtable)=paises
# Paso 2 Se utiliza for e if para realizar y registrar el análisis de regresión y prsentar una conclusión:
for (regid in 1:length(paises)){
ecuacion=paste(paises[regid],"~EEUU",sep="") # Generamos ecuación para comando lm()
regout=lm(ecuacion,data=Qdata) # Corremos regresión
# Extraemos los coeficientes:
regtable[regid,1]=round(summary(regout)$coefficients[1,1],4)# alpha
regtable[regid,2]=round(summary(regout)$coefficients[2,1],4)# beta
regtable[regid,3]=round(summary(regout)$sigma,4)# err.est.residuales
regtable[regid,4]=round(summary(regout)$r.squared,4)# R^2 ajustado
# Registrar la conclusión en el vector correspondiente:
if (summary(regout)$coefficients[2,4]>0.05){
conclusion[regid,1]="Sin relación estadística"
} else {
conclusion[regid,1]="Con relación estadística"
}
}
# Concatenamos la tabla de regresiones y de conclusiones:
regtable=cbind(regtable,conclusion)
regtable
Ya que se generó la tabla de análisis de salida en el objeto regtable
, se puede exportar la misma como unarchivo de excel. Esto tal como se presentó en la sección Exportación de tablas de datos a excel o un archivo *.csv. Incluso con los parámetros de formato que se mencionaron.
Ya para concluir estas notas veremos cómo hacer gráficas para presentar en nuestros reportes. Como punto de partida, se pueden generar gráficas como las que genera R
en su procesador original. Incluso, algunas paqueterías y comandos generan gráficas precargadas o pre hechas por los autores. Por ejemplo, el objeto regout
logrado con el comando lm()
que se describió en el ejemplo anterior tiene varios tipos de gráficas prehechas de interés que se generan con el comando plot()
(gráficar). Veamos las mismas:
# Gráfica de valores ajustados v.s. los residuales
grafica1=plot(regout,1)
grafica1
## NULL
# Gráfica de ajuste de los residuales a la probabilidad gaussiana
grafica1=plot(regout,2)
grafica1
## NULL
# Gráfica de ajuste de valores estimados de Y v.s. raíz cuadrada de residuales estandarizados absolutos
grafica1=plot(regout,3)
grafica1
## NULL
# Gráfica de ajuste de ajuste de Cook
grafica1=plot(regout,4)
grafica1
## NULL
Algunas de estas gráficas pueden lograrse con una sintaxis simple como esta:
grafica2=plot(Qdata$EEUU,Qdata$México,col="blue",xlab="PIB EEUU",ylab="PIB MÉXICO")# Se grafica el diagrama de dispersión en azul
regout=lm(Qdata$México~Qdata$EEUU)
abline(regout,col="red")# Se pone una línea recta, empleando la alpha y beta del modelo en regout
grafica2
## NULL
Sin embargo, las mismas carecen de diseño visual amigable y no permiten incluso que se pueda señalar un dato en la gráfica para conocer su valor. Para el primer caso se tiene la librería ggplot2
y, para gráficas interactivas,la librería plotly
que utiliza la anterior. Veamos cómo hacer la gráfica anterior con ggplot
.
Como es estándar, debemos tener la librería ggplot2
instalada pero la misma viene como complemento de la libreria plotly
que revisaremos en breve. Por tanto se le sugiere instalar esta última con el comando install.packages("plotly")
. Ya que tenemos la misma, trabajemos con el comando ggplot
con un ejemplo:
library(ggplot2) # Se invoca la librería
regchart=ggplot(Qdata,aes(x=Qdata$EEUU,y=Qdata$México))# Genera objeto ggplot, especificando los datos a incluir
# el comando aes() se refiere a los datos del eje x y el eje y. Incluso sirve para agrupar.
regchart=regchart+geom_point(colour="blue") # Agrega al objeto ggplot un objeto de gráfica de puntos o dispersión
# Esto con color azul
regchart=regchart+geom_smooth(colour="red",method="lm") # Agrega una línea de suavizamiento de datos, empleando
# el método "lm" que es el comando de regresión previamente utilizado y el color rojo
regchart=regchart+xlab("PIB EEUU")+ylab("PIB México")
regchart # Imprime o evalúa el objeto ggplot para mostrar la gráfica generada
jpeg(filename = "imagen.jpeg", width=22,height=15,units="cm",res=300,quality=100)
print(regchart)
dev.off()
## quartz_off_screen
## 2
tiff(filename = "imagen.tiff", width=22,height=15,units="cm",res=300)
print(regchart)
dev.off()
## quartz_off_screen
## 2
pdf("imagen.pdf", width=22,height=15)
print(regchart)
dev.off()
## quartz_off_screen
## 2
library(plotly)
regchart2=plot_ly(x=~Qdata$EEUU)
regchart2=add_markers(regchart2,y=~Qdata$México)
regchart2=regchart2%>%add_lines(x=Qdata$EEUU,y=fitted(regout))
regchart2