Está en la página 1de 168






  

 

    






 






 






 



 



       

 #  $%& &

 



 
  
    !
"! 
1

INTRODUCCIÓN A LA ESTADÍSTICA COMPUTACIONAL


APLICACIONES CON EL SOFTWARE ESTADÍSTICO R

ELMER RODRÍGUEZ STEVEZ 1


Maestría en Estadística Aplicada

Universidad del Norte

e-mail: estevez@uninorte.edu.co

Barranquilla – Colombia 2020

1 E. Rodríguez Stevez. Estas notas de clase cubren una pequeña parte en el manejo del software estadístico R a través de
la estadística descriptiva e inferencial, nociones de programación en R, diseño de gráficos estadísticos fundamentales y
avanzados, simulación estadística y diseño de aplicaciones web interactivas. Existe una amplia bibliografía en todos los
campos del saber estadístico (la mayoría en inglés) sobre el manejo del R y sus aplicaciones. La reproducción de estas notas
es libre para alumnos de la Maestría en Estadística Aplicada para su uso privado. Toda otra manipulación requiere permiso
expreso del autor.
2 Logo Imágenes. https://www.r-project.org/logo/ https://rstudio.com/about/logos/
2

Tabla de Contenido
UNIDAD 1 ............................................................................................................................................... 5
1.1. Breve historia del Software Estadístico R y Preliminares ......................................................... 5
1.1.1. ¿Qué es R?............................................................................................................................ 5
1.1.2. Instalando R en tu computador paso a paso ........................................................................... 7
1.1.3. Otras interfaces de trabajo del Software R............................................................................. 8
1.1.4. Antes de empezar a trabajar con R: Seleccionando un directorio de trabajo....................... 9
1.1.5. Fuentes o documentación adicional acerca del manejo de R y sus últimas actualizaciones .... 9
1.1.6. Ayudas, recursos y cursos interactivos gratuitos.................................................................. 10

1.2. Empezando R por primera vez ................................................................................................. 11


1.2.1. Interfaz............................................................................................................................... 11
1.2.2. Vista Inicial ........................................................................................................................... 11
1.2.3. Pasos iniciales ..................................................................................................................... 13
1.2.3.1. Ayuda y documentación .................................................................................................... 13
1.2.3.2. Demostraciones de las funciones de R .............................................................................. 14
1.2.3.3. Bibliotecas en R ................................................................................................................ 14
1.2.3.4. Instalando paquetes .......................................................................................................... 15
1.2.3.5. Ver y modificar datos ya existentes.................................................................................... 17
1.2.3.6. Nombre de las variables en un conjunto e datos ................................................................ 17
1.2.3.7. Conjunto de datos que se encuentran cargados en R ........................................................ 18
1.2.3.8. Ver y borrar objetos que se han creado en una sección ..................................................... 18

1.3. LA MATEMÁTICAS EN R.......................................................................................................... 19


1.3.1. R como una calculadora básica ........................................................................................... 19
1.3.2. R como una calculadora científica ........................................................................................ 20
1.3.3. Parte Entera y módulo ........................................................................................................ 21
1.3.4. Redondeando decimales a enteros .................................................................................... 22
1.3.5. Resumen de los operadores básicos .................................................................................... 22

1.4. VECTORES EN R...................................................................................................................... 23


1.4.1. Creando o generando un vector numérico o de caracteres ................................................... 23
1.4.1.1. Vectores numéricos y asignaciones................................................................................... 23
1.4.1.2. Generando vectores de una secuencia aritmética .............................................................. 24
1.4.1.3. Generando vectores mediante ecuaciones ........................................................................ 24
1.4.1.4. Generando vectores de caracteres .................................................................................... 25
1.4.1.5. Generando vectores aleatorios .......................................................................................... 26
1.4.1.6. Nombrando los elementos dentro de un vector .................................................................. 27
1.4.1.7. Ordenar un vector y seleccionar un elemento de un vector ................................................ 27
1.4.1.8. La función “which” aplicada a vectores .............................................................................. 28
1.4.1.9. Vectores aplicados en funciones ....................................................................................... 29
1.4.1.10. Vectores recortados (“Trimming vectors”) usando subscritos negativos............................ 30
1.4.2. La función Sample................................................................................................................ 31

1.5. MATRICES EN R........................................................................................................................ 34


1.5.1. Las matrices y sus operaciones............................................................................................ 34
1.5.2. Etiquetando las filas y columnas de una matriz..................................................................... 36
1.5.3. Cálculos sobre filas y columnas de matrices ......................................................................... 37
1.5.4. Operaciones básicas ............................................................................................................ 37
1.5.5. Suma y resta de matrices ..................................................................................................... 38
1.5.6. Multiplicación de matrices..................................................................................................... 38
1.5.7. Determinante de una matriz................................................................................................. 38
1.5.8. Inversa de matrices .............................................................................................................. 39
1.5.9. Descomposición espectral de una matriz .............................................................................. 40
1.5.10. Las funciones rbind y cbind ................................................................................................ 41
1.5.11. Matriz diagonal ................................................................................................................... 43
3
1.6 TABLAS DE DATOS (Dataframes) + TIBBLES ......................................................................... 46
1.6.1. Importando Dataframes y análisis numérico .......................................................................... 46
1.6.2. Subscritos e índices para Dataframes................................................................................... 48
1.6.3. Ordenando Dataframes ........................................................................................................ 50
1.6.4. Usando condicionales lógicos para seleccionar filas de una tabla de datos ........................... 51
1.6.5. Otra clase de extracciones para una tabla de datos .............................................................. 52
1.6.6. Omitiendo filas que contengas valores faltantes, NA ............................................................. 54
1.6.7. Creando una tabla de datos (Dataframes)............................................................................. 55
1.6.8. Usando la función match en Dataframes............................................................................... 56

1.7. PROGRAMANDO CON R........................................................................................................... 58


1.7.1. Motivación............................................................................................................................ 58
1.7.2. Componentes básicos de un programa ................................................................................. 58
1.7.3. Bibliografía de apoyo a la programación ............................................................................... 59
1.7.4. ¿cómo construir e invocar una función? ................................................................................ 59
1.7.5. Notas importantes para tener en cuenta al momento de crear una función ........................... 61
1.7.6. Tipos de símbolos en el interior de una función ..................................................................... 61
1.7.7. Estructuras de control........................................................................................................... 62
1.7.8. Estructuras de repetición, bucles o loops definidas e indefinidas .......................................... 66
1.7.7. Programación eficiente ......................................................................................................... 69

UNIDAD 2 ............................................................................................................................................. 71
PROGRAMACIÓN DE GRÁFICOS CON R ........................................................................................ 71

UNIDAD 3 ........................................................................................................................................... 114


SIMULACIONES EN R .................................................................................................................... 114

UNIDAD 4 ........................................................................................................................................... 128


ANÁLISIS E INTERPRETACIÓN DE ALGUNOS TOPICOS DE ESTADÍSTICA INFERENCIAL Y
REGRESIÓN....................................................................................................................................... 128

UNIDAD 5 ........................................................................................................................................... 146


EL MÉTODO BOOTSTRAP Y SUS APLICACIONES ....................................................................... 146

UNIDAD 6 ........................................................................................................................................... 164


Generación de aplicaciones web interactivas con Shiny ................................................................... 164
4

Webgrafía asociada a estas notas:


 R Core Team (2016). R: A language and environment for statistical computing. R Foundation for
Statistical Computing, Vienna, Austria. URL https://www.R-project.org/.

 Introducción a R— R Development Core Team—Traducción de Andrés González y Silvia González. -


http://cran.r-project.org/doc/contrib/R-intro-1.1.0-espanol.1.pdf

 R para principiantes— Emmanuel Paradis—Traducción de Jorge A. Ahumada.


http://cran.r-project.org/doc/contrib/rdebuts_es.pdf

 Gráficos Estadísticos con R — Juan Carlos Correa y Nefi González. Universidad Nacional. Sede Medellín.
Año 2002. - http://cran.r-project.org/doc/contrib/grafi3.pdf

 R news and tutorials contributed by (573) R bloggers - http://www.r-bloggers.com/

 R, estadística y tratamiento masivo de datos (alternativa a SAS, ACL e IDEA) -


http://www.marblestation.com/?p=794

 Quick-R. Accesing The power of R - http://www.statmethods.net/

 Programming in R - http://zoonek2.free.fr/UNIX/48_R/02.html

 R plot and graph gallery - http://www.sr.bham.ac.uk/~ajrs/R/r-gallery.html

 R graph gallery: A collection - http://rgraphgallery.blogspot.com/2013/04/rg-plotting-boxplot-and-


histogram.html

 Fundamentos estadísticos para investigación. Introducción a R. Antonio Maurandi López, Laura del Río
Alonso y Carlos Balsaobre Rodríguez.

https://www.researchgate.net/publication/275349583_Fundamentos_estadisticos_para_investigacionIn
troduccion_a_R
5
_______________________________________________________________________________________________________________________

UNIDAD 1
______________________________________________________________________________________________

1.1. Breve historia del Software Estadístico R y Preliminares

1.1.1. ¿Qué es R?

Un programa estadístico computacional para el análisis de datos.

Un lenguaje orientado a objetos: Esto significa que las variables, datos, funciones, resultados,
etc., se guardan en la memoria activa del computador en forma de objeto con un nombre
específico.

Un objeto es un elemento del programa que integra sus propios datos y su propio funcionamiento,
es decir, un objeto está formado por datos (propiedades o atributos) y por las funciones que es capaz
de realizar el objeto (métodos). Sin embargo, para hacer posible lo anterior, hay que definir primero
una clase que es lo que define a un tipo de objeto. Al definir una clase lo que se hace es indicar como
funciona un determinado tipo de objeto.

Fuente: Poo

Un lenguaje de programación …
 Diseñado por estadísticos y para estadísticos.
 Con un manejo efectivo de los datos y facilidad de almacenamiento.
 Con un conjunto completo de operadores para realizar cálculos matemáticos.
 Con una gran colección de herramientas que se muestran de una manera coherente e
integrada para el análisis de datos.
 Con facilidades gráficas de alta definición para el análisis de la información, dando así a
trabajos de investigación (artículos científicos) o presentaciones en diapositivas, un gran
toque de profesionalismo.
6

Un entorno…
 Flexible y poderoso para la investigación computacional.

 Que contiene una librería llena de algoritmos para acceder a un gran conjunto de datos
y funciones que se pueden manipular, analizar y graficar.

 Que puede integrar programas escritos en otros programas, tales como C, C++,
Fortran, Python y Java.

Fuente: Lenguajes de Programación

Un software con “Sistema Abierto”.


 Un programa libre de costos, descargable vía Internet.
 Distribuido bajo la licencia GPL (General Public Licence). Proyecto creado en 1982
por Richard Stallman (iniciador de la “Fundación Software Libre” en el mundo). Ver
Video.
 Completamente disponible para todo el mundo, donde se puede ver el código del
programa y proponer cambios (contribuyentes).
 Disponible en muchas plataformas: Unix, Linux, Mac y versiones superiores a Windows
95.

Fuente: GPL

Fuente: Richard Stallman

Una comunidad.
 Muchos contribuyentes conocidos como el “Grupo Nuclear de Desarrollo de R” y más
de 3 millones de usuarios.
 Recursos, ejemplos y ayudas en cada dominio.
 Admisible para no-especialistas en programación.
7

Toda una historia.


 Basado bajo el lenguaje de programación “S”.
 “S” es un Sistema y un Lenguaje para organizar, visualizar y analizar datos.
 “S” está disponible como el programa “S” – PLUS comercializado por “Insightful
Corporation” (proveedor de análisis de datos estadísticos y softwares).
 En 1976, “S” fue desarrollado por Jhon Chambers, Rick Becker y Allans Wilks en
los Laboratorios Bell de AT&T (AT&T’s Bell Laboratories).
 En 1991, dos estadísticos Robert Gentleman (canadiense) y Ross Ihaka (neozelandés) de la
universidad de Auckland en Nueva Zelanda, querían experimentar con el programa “S”,
donde desarrollaron una versión más reducida, la cual llamaron R.
 El nombre R proviene de las iniciales de sus nombres.
 No fue hasta 1993 que hicieron su primer anuncio al público.
 En 1995, Martin Mächler convenció a Ross y Robert para usar la GPL para hacer de R un
software libre de costos (como un recurso disponible para su manipulación y
mejoramiento).
 En 1997, El grupo “R Core” es formado y es quien controla los códigos fuente de R.
 Para el año 2000, se libera la primera versión del Software R.
 En la actualidad, la versión más reciente es la 3.6.2 (subida el jueves, 12 de diciembre de
2019), la última liberada al momento de actualizar estas notas, la cual se trabaja bajo el
ambiente RGui de Windows (Interface gráfica estándar para usuarios de R).

LEE LAS ÚLTIMAS NOTICIAS


8

1.1.2. Instalando R en tu computador paso a paso

1. Ir a la página http://cran.r-project.org/ 1
2. Hacer click en Download R for Windows o de acuerdo al Sistema Operativo que tengas,
ya sea Linux o Mac.
3. Hacer click en el subdirectorio base o hacer click en install R for the firsttime.
4. Hacer click en Download R 3.6.2 for Windows (62 megabytes, 32/64 bit).
5. Ir al archivo ejecutable con el nombre de R-3.6.2-win.exe y seguir las instrucciones de
descarga.

Importante: Dentro de los pasos de instalación este preguntará si desea correr el programa
bajo 32 – bit o 64 – bit. Mi recomendación es hacer la selección de acuerdo al tipo de Sistema
que tenga tu equipo. Este se puede verificar haciendo clic en “Inicio”, “Configuración”,
“Panel de Control” y finalmente en “Sistema”, confirmando así la misma.

6. Al finalizar todos los pasos anteriores se debió crear un icono del programa sobre
tu escritorio.

Nota: El equipo de programadores estadísticos en promedio, realizan dos veces al año nuevas versiones
de R. Por ejemplo, recodemos que ésta última versión se publicó el jueves 12 de diciembre de 2019.
Para una próxima versión habrá que estar atentos a la página oficial del programa R.

1CRAN (The Comprehensive R Archive Network) es una red de servidores FTP y web de todo el mundo en donde se puede almacenar o
descargar archivos del programa R tales como los instaladores, paquetes y documentación para aprender a manejar el lenguaje de
programación.
9

1.1.3. Otras interfaces de trabajo del Software R

En la actualidad existen diferentes tipos de interfaces de trabajo para el análisis estadístico con R, creados
por distintos equipos de ingenieros de software; sin embargo, el mejor de todos hasta el momento es
RStudio, diseñado por un equipo de programadores de software liderado por el norteamericano Joseph J.
Allaire. Otra interface muy empleada por iniciadores es Rcommander. Cada uno de ellas se explica a
continuación:

RStudio: http://www.rstudio.com/ es una interface más amigable para el uso personal en el


análisis de datos estadísticos que la interface básica R-GUI, es debido a que se compone de cuatro
ventanas bien distribuidas que permite al usuario disponer en una sola mirada la ventana de
entrada (editor de texto o script de resaltado de sintaxis que soporta la ejecución de código directo),
la ventada de salida (consola), la ventana de gestión de espacio de trabajo e historiales y finalmente
la ventana multipropósito (en donde se muestra las opciones de vista de archivos, vista de gráficos,
vista de instalación e invocación de librerías y vista de ayuda en general).

Rcommander: es una interface que se instala dentro del R básico mediante el paquete “Rcmdr”
el cuál es mucho más amigable que los dos ambientes anteriores, principalmente para las personas
que se sientan más cómodas con el método de “cliquear” en lugar del método de “escritura de
comandos”, debido a que su apariencia es muy parecida a la de programas tales como SPSS,
STATGRAPHICS, STATA, entre otros.

Para su instalación puede guiarse del siguiente video tutorial que fue tomado de
YouTube: https://www.youtube.com/watch?v=0Yz4mtfGOtY

R Portable: como su nombre lo indica es la opción que tiene el usuario de portar el programa
por medio de una memoria USB o disco duro extraíble, sí este tiene la limitación de poseer un
computador personal y poder llevarla a todos lados. Esta opción se presenta tanto para la interface
básica como la de RStudio. Los links de instalación se muestran abajo:

R-GUI: https://sourceforge.net/projects/rportable/

RStudio: https://sourceforge.net/projects/rportable/files/R-Studio/0.97.551/
10

1.1.4. Antes de empezar a trabajar con R: Seleccionando un


directorio de trabajo.

Antes de iniciar R, es muy importante poder guardar todo nuestro trabajo o funciones que hayamos
creado, los cual se guardaran como un archivo con extensión .RData (Interfaz: Entorno gráfico Rgui).

A su vez también es importante guardar el historial de una sección en R, donde se podrán ver todos
los comandos que se hayan empleado en esa sección. Este se salvará como un archivo editable con
extensión .Rhistory (Interfaz: Bloc de notas)

Estos dos archivos se pueden guardar simultáneamente mediante los siguientes pasos:

o Crear una carpeta ya sea sobre el escritorio, en una USB o en mis documentos con el nombre
que ustedes crean más apropiado.
Por ejemplo: Trabajos.EC

o Ir a las propiedades de la carpeta creada para copiar la ubicación de la misma.


Por ejemplo: C:\Users\ELMER RODRIGUEZ\Desktop

o Ir a las propiedades del icono del programa R, y pegar la ubicación de la carpeta en donde dice
“Iniciar en:” añadiendo el nombre que le hayas asignado a lacarpeta.
Por ejemplo: " C:\Users\ELMER RODRIGUEZ\Desktop\Trabajos.EC”

Finalmente, para verificar que efectivamente todo surgió efecto; primero abra el programa R, luego
haga click en el ícono resaltado (ver figura abajo) denominado (guardar área de trabajo) de la barra de
herramientas del programa, luego guardar y finalmente cerrar el programa R. De lo anterior, dirigirse
a la carpeta creada Trabajos.EC, para verificar que efectivamente se hayan creado los dos archivos: el
de “.Rhistory” que debe abrir como un documento con extensión “.txt” (bloc de Notas) y el otro llamado
“R” con extensión “.RData”.

Nota: De aquí en adelante se aconseja abrir el software usando la extensión R.RData (elicono )

1.1.5. Fuentes o documentación adicional acerca del manejo de R y


sus últimas actualizaciones.

o Visitar la página oficial del programa R en https://www.r-project.org/

o Descargar los manuales de la página https://cran.r-project.org/manuals.html en particular, revisar


los que dicen R-intro.pdf y R-data.pdf.

o De la página principal podrás descargar muchos libros de tu interés como bibliografía adicional
para tu aprendizaje en R (no todos son descargables de manera gratuita). Este se encuentra en
la parte de “Documentation” – “Books” de la páginaoficial.
11

1.1.6. Ayudas, recursos y cursos interactivos gratuitos

o Buscar todo tipo de ayuda: RSeek o Google.


o Para aprender más sobre un paquete o una función pueden visitar: rdocumentation.org
o Curso para aprender los comandos básicos de R Try R y DataCamp cuentan con excelentes
cursos interactivos.
o Para mantenerse al tanto de las noticias de la comunidad de R pueden visitar R -Bloggers.
o Desde RStudio crear documentos con el lenguaje de programación R Markdown y poderlos
publicar a la Web mediante R Pubs.
12

1.2. Empezando R por primera vez

1.2.1. Interfaz

Existen diferentes entornos gráficos que facilitan la interacción con el usuario (llamados GUI, del inglés
Graphical Users Interface). Entre los más populares se encuentra RGui (disponible para Windows),
RStudio (Windows, MacOS, Linux), Tinn –R (Windows, MacOS), R Commander (Windows, MacOS,
Linux), Emacs (Windows, MacOS, Linux), RKward (Linux), pero existen muchos otros. Para efectos del
curso trabajaremos en tres tipos de entornos: RGui en Windows, RStudio y R Commander para
Windows tal como se mencionó anteriormente.

1.2.2. Vista Inicial

Para iniciar R se hace click en el acceso directo R 3.6.2 (o versión que tenga en el momento) o en Inicio 
Todos los Programas  R  R x64 3.6.2. En la pantalla de RGui aparece la ventana Consola de R con un
mensaje introductorio donde muestra la versión del software con que se está trabajando (acompañado
de la fecha de publicación), los derechos de autor (acompañado del nombre de la Fundación) y la
plataforma en la cual está trabajando el equipo. Este finaliza con un prompt o apuntador ‘>’, lo que
indica que R ya está listo para trabajar, o preguntándose ¿ahora qué hago?

La siguiente pantalla muestra el aspecto de la interfaz RGui, disponible para Windows.


13

RGui se instala de forma automática con el paquete base de Windows. El resto de GUis es necesario
instalarlas específicamente. Se encuentran gratuitamente en Internet.

Estas GUis, para facilitar la interacción con el usuario, disponen de una serie de menús desplegables,
cuya complejidad puede ir desde hacer solamente algunas operaciones sencillas como en el caso de
hacer una edición, apertura de ficheros, guardar datos, cargar paquetes, actualizaciones, etc, de R
Commander y RKward.

---------------------------------------------------------------------------------------------------------------------

Como una opción personal es posible cambiar la apariencia del prompt así:

options(prompt="nombre>")
Por ejemplo:
options(prompt="E>")

E>
Sin embargo, si se desea revertir el prompt como estaba anteriormente:
options(prompt=">")

>
--------------------------------------------------------------------------------------------------------------------––––

El Equipo Central de Desarrollo de R (R Core Team) y la muy activa comunidad de autores de los
paquetes han invertido mucho tiempo y esfuerzo creando lo que es hoy en día R.

Ejecutemos las función contributors(), licence() y citation() para saber quiénes son los
contribuyentes en la creación y crecimiento de lo que hoy es R en la actualidad. La licencia que la
respalda y el formato de cita que hay que emplear al momento de hacer uso y beneficiarse del
programa.
14

1.2.3. Pasos iniciales

1.2.3.1. Ayuda y documentación

Para obtener cualquier tipo de ayuda, información, descripción general y la lista de argumentos
para el buen uso de una función en específico, se escribe:
help ("nombre de la función”)
Un comando más corto sería:
? nombre de la función
Por ejemplo:
help("mean")

ó
?mean
Otras funciones muy útiles son find y apropos. La primera ayuda a ubicar en qué paquete se
encuentra un objeto y la segunda encuentra todos los objetos con los nombres parciales que se le
ha asignado a éste, es decir:
find("nombre del objeto")
[1] "package: nombre del paquete donde se encuentra ubicado el objeto"
apropos("nombre parcial del objeto o función")

Por ejemplo:
find("cov")
## [1] "package:stats"

apropos("norm")
## [1] "dlnorm" "dnorm" "norm" "normalizePath"
## [5] "plnorm" "pnorm" "qlnorm" "qnorm"
## [9] "qqnorm" "rlnorm" "rnorm"
15

Para adquirir manuales de apoyo, referencias y material adicional con respecto al manejo de R,
dentro del mismo programa, se escribe en el prompt así:
help.start()

Suponiendo que se nos ha olvidado el nombre exacto de una función o que desconocemos en qué
paquete se encuentra un conjunto de datos (data.frames) o simplemente queremos ver un tema o
un concepto en específico, entonces se emplea la función help.search ().
Por ejemplo:
help.search("linear model")

1.2.3.2. Demostraciones de las funciones de R


Los siguientes comandos son útiles para ver el gran desempeño de lo que R puede hacer.
demo(persp)

demo(graphics)

demo(Hershey)

demo(plotmath)

1.2.3.3. Bibliotecas en R
Para usar una de las bibliotecas, simplemente se debe escribir la función library con el nombre
de la biblioteca dentro de los paréntesis.
Por ejemplo:
library(MASS)

De manera general, si queremos saber la lista de paquetes y la descripción de cada uno de ellos
que hay en nuestra biblioteca de R, escribimos:
library()

Ahora si queremos saber sobre la información completa de la biblioteca MASS que previamente
hemos invocado, es decir, conocer la descripción de la misma, las funciones y conjunto de datos
que posee, escribimos:
library(help=MASS)
16

De otro modo podemos también ver el contenido completo de la biblioteca en orden alfabético
sin distinción de una función o conjunto de datos, de la siguiente manera:
Nota: La siguiente lista solo muestra los primeros 30 objetos.

objects(grep("MASS",search()))

## [1] "abbey" "accdeaths" "addterm"


## [4] "Aids2" "Animals" "anorexia"
## [7] "area" "as.fractions" "bacteria"
## [10] "bandwidth.nrd" "bcv" "beav1"
## [13] "beav2" "biopsy" "birthwt"
## [16] "Boston" "boxcox" "cabbages"
## [19] "caith" "Cars93" "cats"
## [22] "cement" "chem" "con2tr"
## [25] "contr.sdif" "coop" "corresp"
## [28] "cov.mcd" "cov.mve" "cov.rob"

1.2.3.4. Instalando paquetes

Para la instalación de paquetes en R, se puede realizar mediante dos formas:

1. Escribiendo en el prompt:

install.packages("nombre del paquete", dep=TRUE)

Nota: El argumento << dep= TRUE >>, indica que se instalen también las dependencias de ese
paquete. La dependencias son otros paquetes que contienen elementos necesarios para que
funcionen todas las aplicaciones que hay en el paquete que queramos instalar.

2. En la barra de Menú del programa seguir los siguientes pasos:


17

Seleccionamos como ventana del CRAN (The Comprehensive R Archive Network) a Colombia
(Bogotá):

Elegimos el paquete o biblioteca a descargar, por ejemplo faraway:


18

1.2.3.5. Ver y modificar datos ya existentes

Para ver y editar un conjunto de datos ya existente dentro de R, se realiza los siguientes pasos:
Por ejemplo, dentro de la biblioteca de MASS, se encuentran muchos conjuntos de datos
interesantes para realizar su análisis estadístico. Por ejemplo, si queremos ver o editar el conjunto
de datos "wtloss", escribimos:
library(MASS)

wtloss

head(wtloss)

## Days Weight
## 1 0 184.35
## 2 4 182.51
## 3 7 180.45
## 4 7 179.91
## 5 11 177.91
## 6 18 175.81

fix(wtloss)

Importante: Si por alguna razón al momento de querer editar un conjunto datos y R muestra un
error diciendo que no se puede ejecutar esa acción, entonces existe una opción llamada attach que
permite poder hacer dichos cambios.
# La función attach permite vincular o enganchar los datos para su manipulación.

attach(wtloss)

fix(wtloss)

1.2.3.6. Nombre de las variables en un conjunto e datos

Si queremos saber que variables contiene cualquier conjunto de datos, en particular el de


"wtloss", se escribe lo siguiente:
names(wtloss)
## [1] "Days" "Weight”
19

1.2.3.7. Conjunto de datos que se encuentran cargados en R

IMPORTANTE: Durante todo el curso de Estadística Computacional, estaremos realizando la


mayoría de nuestros análisis mediante dos grandes paquetes, ya descargados previamente a R,
que son: {datasets} y {MASS}. Pero aún así haremos uso de muchos otros.
Ahora para ver el conjunto de datos que contiene cada uno de ellos con su respectiva
descripción, previamente "invocados" por la función library, se escribe en el prompt lo
siguiente:
data()

Ahora, si queremos ver todos los conjuntos de datos disponibles que hay en R sin haber
invocado antes la biblioteca, se escribe:
data(package = .packages(all.available = TRUE))

1.2.3.8. Ver y borrar objetos que se han creado en una sección

Para ver todos los objetos (variables, vectores, funciones, conjunto de datos, rutinas, etc...) que se
han creado en una sesión de R actual, se escribe lo siguiente:
ls()
## character(0)

ó
objects()
## character(0)

Nota: De la salida anterior “character (0)” indica que no hay ningún objeto en
lista.

Ahora, de esa lista de objetos, si queremos borrar alguno de ellos, escribimos:


rm(nombre)
O de lo contrario, si se desea borrar toda la lista, se escribe:
rm(list=ls())
20

1.3. LA MATEMÁTICAS EN R

1.3.1. R como una calculadora básica

Hacer cálculos matemáticos en R es muy sencillo, tal como manejar una calculadora científica, los
comandos que se emplean son bastante simples.
Estos son algunos ejemplos:
5+3+10-3
## [1] 15

8*10
## [1] 80

8*10/20
## [1] 4

sqrt(144)
## [1] 12

10^5
## [1] 1e+05

Dos o más expresiones pueden ser calculadas sobre una misma línea, siempre y cuando ésta se
pueda separar por punto y coma ( ;).
Por ejemplo:
5+8; 120-100; 2*sqrt(81)-50/5
## [1] 13

## [1] 20

## [1] 8
21

1.3.2. R como una calculadora científica


La siguiente tabla muestra las diferentes funciones más utilizadas en R.

Tomado del libro: The R Book. Michael Crawley. Pag. 17. Ver libro electrónico.

Recordatorio: Si escribimos demo(plotmath) en el prompt, podrán ver mucho más funciones y


símbolos matemáticos que se pueden utilizar. Además, en el archivo de PDF “Short – refcard” del Google
Drive, se muestran muchas más funciones útiles.
22

1.3.3. Parte Entera y módulo

Suponiendo que queremos saber cuántas veces el 13 cabe en 243, entonces debemos calcular la
parte entera del mismo, es decir:
243%/%13
## [1] 18

Ahora del ejercicio anterior podemos saber su residuo o cómo llamaremos de aquí en adelante
módulo, es decir:
243%%13
## [1] 9

El módulo es una herramienta muy útil en matemáticas para saber:


a. Si un número es par o impar: Un número es impar si al dividir éste número por 2, el
módulo de éste es 1 y un número es par si al dividir éste número por 2, el módulo de éste es
0, es decir:
7867%%2
## [1] 1

8980206%%2
## [1] 0

b. Si un número es un múltiplo exacto de algún otro número. En R podemos preguntarasí:


¿Será que 876543 es un múltiplo de 7?
876543%%7==0
## [1] FALSE

¿Será que 876543 es un múltiplo de 3?


876543%%3==0
## [1] TRUE
23

1.3.4. Redondeando decimales a enteros

Existen diferentes formas de redondear un número, ya sea redondear al próximo entero, al


entero inferior o redondear al entero más cercano. Los comando a utilizar son:
 Redondear 5.65 al próximo entero.
ceiling(5.65)
## [1] 6

 Redondear 5.65 al entero inferior


floor(5.65)
## [1] 5

 Redondear 8.47 y 8.53 al entero máscercano


redondeo=function(x)
floor(x+0.5)
redondeo(8.47)
## [1] 8

redondeo(8.53)
## [1] 9

1.3.5. Resumen de los operadores básicos


R utiliza muy a menudo los siguientes operadores:

Tomado del libro: The R Book. Michael Crawley. Pag. 19. Ver libro electrónico.
24

1.4. VECTORES EN R

Los vectores en R son variables con uno o más valores del mismo tipo: ya sea lógico, entero, real,
complejo, o simplemente de caracteres. Recordemos que en matemáticas por ejemplo 5.2 es
considerado como un valor escalar, sin embargo, en R un escalar es un vector de longitud 1.

1.4.1. Creando o generando un vector numérico o de caracteres

Los valores pueden ser asignados a un vector de muchas maneras. Ya sean valores que se le asignen al
vector dado unos números cualesquiera, valores generados por una secuencia constante o fija,
mediante una ecuación, generando vectores de caracteres o de valores aleatorios.

1.4.1.1. Vectores numéricos y asignaciones

Por ejemplo, si queremos asignarle al vector k, los siguientes valores: 2, 8.5, 5, 6.1, 4.7, 15, 9. En R se
puede escribir de varias formas:

k=c(2, 8.5, 5, 6.1, 4.7, 15, 9) #aquí empleamos la función "c": encadena o enlaza valores numéricos.
k
## [1] 2.0 8.5 5.0 6.1 4.7 15.0 9.0

assign("k1",c(2, 8.5, 5, 6.1, 4.7, 15, 9)) #aquí empleamos la función "assign": asigna un valor o
conjunto de valores a un nombre en específico.
k1
## [1] 2.0 8.5 5.0 6.1 4.7 15.0 9.0

k2=scan() #aquí empleamos la función "scan": lee los datos de una lista de valores.
k2
## numeric(0)

Nota: Si quisiera verificar ya sea la longitud del vector que he creado o del conjunto que he
importado, se utiliza la función "length". Es decir que si queremos verificar por ejemplo el
número de elementos que contiene el vector k, escribimos lo siguiente:
length(k)
## [1] 7

Importante: Esta función es muy empleada en la creación de funciones y desarrollo de


simulaciones.
25

1.4.1.2. Generando vectores de una secuencia aritmética

Suponga que deseamos generar un vector numérico de valores enteros positivos del 1 al 10, y que le
llamaremos “conteo”. En el prompt podemos escribir de las siguientes maneras:

conteo=1:10 # Aquí utilizamos el operador : para generar secuencias de uno en uno


conteo
## [1] 1 2 3 4 5 6 7 8 9 10

conteo=seq(1,10,by =1) # la función "seq": se emplea para generar secuencias más complejas. El
argumento "by": indica el incremento de la secuencia.
conteo
## [1] 1 2 3 4 5 6 7 8 9 10

conteo=seq(1,10,length=10) ; conteo # el signo punto y coma " ; " actúa como salto delínea.
## [1] 1 2 3 4 5 6 7 8 9 10

(conteo=rep(1:10,each=1)) # la función rep, se emplea también para generar secuenciascon


repeticiones
# cuando una función u objeto está entre paréntesis ( ), no es necesario invocar su nombre para
que muestre su salida.
## [1] 1 2 3 4 5 6 7 8 9 10

1.4.1.3. Generando vectores mediante ecuaciones

Es posible generar vectores numéricos utilizando alguna ecuación matemática. Por ejemplo, sea x un
vector de números enteros del 1 al 10 y sea h un vector de la forma, h = 3x2+5, entonces, si deseáramos
generar un vector numérico para h, bajo las condiciones anteriores, éste sería de la siguiente manera:

x=1:10
h=3*x^2+5
h
## [1] 8 17 32 53 80 113 152 197 248 305
26

1.4.1.4. Generando vectores de caracteres

Los vectores de caracteres son muy empleados en R, por ejemplo en un gráfico de etiquetas, en
tablas o matrices (solo por mencionar algunos). La manera de escribir éste en el prompt es
utilizando la función "c" o la función "paste":
nombres=c("Uni","Norte","Puerto", "Colombia")
nombres
## [1] "Uni" "Norte" "Puerto" "Colombia"

unir=paste(nombres,1:4,sep="")
unir
## [1] "Uni1" "Norte2" "Puerto3" "Colombia4"

unir=paste(c(nombres[1],nombres[3]),c(nombres[2],nombres[4]),sep="")
unir
## [1] "UniNorte" "PuertoColombia"

Importante: Después de haber creado o generados diferentes tipos de objetos, existe una función
que permite saber con qué clase de objeto estamos trabajando, ya sea numérico "numeric", de
caracteres "caracter", una matrix "matrix", una tabla de datos "data.frame", etc., esta es la
función "class". Veamos algunos ejemplos:
k=c(2, 8.5, 5, 6.1, 4.7, 15, 9)
class(k)
## [1] "numeric"

class(nombres)
## [1] "character"

class(Rabbit) #Invoque previamente el paquete MASS.


27

1.4.1.5. Generando vectores aleatorios

Los vectores aleatorios pueden ser generados mediante cualquiera de las diferentes distribuciones de
probabilidades tanto discretas como continuas que nosotros conocemos. Veamos algunos ejemplos:

args(runif) #La función "args" permite saber cuales son los argumentos mínimos necesarios que
debe emplear la función "runif".
## function (n, min = 0, max = 1)
## NULL

runif(10)
## [1] 0.82674452 0.18046766 0.01160646 0.75501017 0.38504994 0.37181526
## [7] 0.45044807 0.25833122 0.12679006 0.48397798

runif(10,4,5)
## [1] 4.432103 4.088384 4.696770 4.163062 4.647785 4.606259 4.739780
## [8] 4.235047 4.232067 4.162095

args(rpois)
## function (n, lambda)
## NULL

rpois(10,100)
## [1] 91 123 96 97 89 76 92 99 105 102

args(rnorm)
## function (n, mean = 0, sd = 1)
## NULL

rnorm(10)

## [1] -0.07784572 -0.03201230 -0.22682614 -0.95589519 0.70244048


## [6] -0.24284870 -0.27491749 0.20897180 0.98217364 0.86521447
28

1.4.1.6. Nombrando los elementos dentro de un vector

Después de haber creado algún vector cualquiera, en ocasiones es muy útil etiquetar cada uno de
sus elementos, ya sea con números o un nombre en específico. Por ejemplo si creamos el vector
15, 28, 10, 4, 21, 18, 35, 9 llamado cuenta, tenemos que:
cuenta=c(15,28,10,4,21,18,35,9)
cuenta
## [1] 15 28 10 4 21 18 35 9

names(cuenta)=0:7 # con este comando se ha creado una tabla de frecuencias


cuenta

## 0 1 2 3 4 5 6 7
## 15 28 10 4 21 18 35 9

Ahora si por ejemplo tenemos ya creada la tabla anterior y solo nos interesa las frecuencias, es
decir, queremos remover los nombres, entonces empleamos la función as.vector así:
as.vector(cuenta)
## [1] 15 28 10 4 21 18 35 9

1.4.1.7. Ordenar un vector y seleccionar un elemento de un vector

Para ordenar un vector o un conjunto de valores, se utiliza el comando “sort(vector)” si es en orden


ascendente y “rev(sort(vector))” si es en orden descendente. Veamos un ejemplo:

Dado el siguiente vector numérico llamado num: ordenarlo de menor a mayor y viceversa.

num=rpois(20,5)
num
## [1] 6 6 9 5 8 3 3 9 7 5 7 2 7 5 1 5 6 9 8 10

Ordenando de menor a mayor tenemos que:


sort(num)
## [1] 1 2 3 3 5 5 5 5 6 6 6 7 7 7 8 8 9 9 9 10

Ordenando de mayor a menor, tenemos que:


rev(sort(num))
## [1] 10 9 9 9 8 8 7 7 7 6 6 6 5 5 5 5 3 3 2 1
29

En algunas circunstancias deseamos obtener o seleccionar alguno de los elementos de un vector en


específico. Los subscritos o índices (denotados en R con [ ]) son empleados para tal fin. Es decir, que
si queremos seleccionar:

(a) el noveno elemento de la lista

(b) extraer los valores de las posiciones pares, del vector anterior “num”.

En el prompt se escribe así:

num
## [1] 3 9 5 7 8 5 5 5 9 3 7 4 6 2 4 3 8 1 7 6

num[9]
## [1] 9

num[seq(2,20,by=2)]
## [1] 9 7 5 5 3 4 2 3 1 6

Importante: Lo anterior es posible también con matrices, arreglos y tabla de datos (“Dataframes”).

1.4.1.8. La función “which” aplicada a vectores

Para saber en qué posición se encuentra un elemento o varios de ellos con cierta característica dentro
de un vector y para saber cuáles son esos elementos, utilizamos la función “which”. Veamos un
ejemplo:

Dado el vector “a” tal como se muestra abajo, indicar cuál de sus elementos son mayores que 5.

a = c(2,5,7,9,3,8,1,3,9,12,7,2,1,5,8,12,1,3)
a
## [1] 2 5 7 9 3 8 1 3 9 12 7 2 1 5 8 12 1 3

which(a>5) #indica el valor posicional de cada uno de los elementos dentro del vector
## [1] 3 4 6 9 10 11 15 16

a[a>5] #indica los elementos que poseen tal característica.


## [1] 7 9 8 9 12 7 8 12
30

1.4.1.9. Vectores aplicados en funciones

Una de las grandes fortalezas de R es su habilidad para evaluar funciones. Las funciones más
empleadas en R, se muestran en la siguiente tabla:

Tomado del libro: The R Book. Michael Crawley. Pag. 41. Ver libro electrónico.

Nota: Podrán encontrar más de ellas en el archivo de PDF: “Listado de Comandos-Referencia Rápida R”,
que se encuentra dentro de la carpeta de Referencias Bibliográficas del Drive.
31

1.4.1.10. Vectores recortados (“Trimming vectors”) usandosubscritos


negativos

Recordemos que los subscritos o índices individuales se refieren mediante corchetes. Entonces, sea el
vector x definido como:

x=c(5,8,6,7,1,5,3,3,8,22,7,9,7,5)
x
## [1] 5 8 6 7 1 5 3 3 8 22 7 9 7 5

Nosotros podemos encontrar el cuarto elemento solo escribiendo:


x[4]

## [1] 7

Es de extrema utilidad emplear subscritos negativos ya que éste permite remover elementos de un
vector. Supongamos que queremos crear un nuevo vector llamado, z, que contenga todos los elementos
de x, excepto el primero.
z=x[-1]
z

## [1] 8 6 7 1 5 3 3 8 22 7 9 7 5

Un ejemplo estadístico: Supongamos que deseamos calcular la media recortada de "x", lo que significa
calcular la media aritmética removiendo sus valores extremos (que para este ejemplo sería 1 y 22).
Para este objetivo se necesita realizar dos pasos: primero se debe ordenar los datos y luego remover
el valor mínimo con x[-1] y el valor máximo con x[-length(x)]. Podríamos hacer esto simultáneamente
enlazando o encadenando ambas instrucciones con -c(1,length(x)). Ahora con lo anterior podremos
crear nuestra segunda función en R, para poder realizar dichocálculo:

media.rec=function (x) mean(sort(x)[-c(1,length(x))])


media.rec
## function (x) mean(sort(x)[-c(1,length(x))])

function (x) mean(sort(x)[-c(1,length(x))])


## function (x) mean(sort(x)[-c(1,length(x))])

media.rec(x)
## [1] 6.083333

STOP Supongamos que un estudiante está muy desesperado y no encuentra el error que

genera su rutina de la media recortada. ¡Cómo usted lo podría ayudar?

media.rec=function (x) sum(sort(x)[-c(1, length(x))]) /length(x)


32
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
ESTRUCTURA BÁSICA DE UNA FUNCIÓN

nombre de la función = function (argumentos) acción que se desea ejecutar

Para ver la función terminada:


nombre de la función

Para correr la función:


nombre de la función(argumentos)

–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
Nota: en la sección 1.7 Programando con R, se hablará con más detalle sobre la estructura y los
diferentes estructuras de control.

1.4.2. La función Sample

Esta función tiene como finalidad tomar una muestra de tamaño especificado de los elementos
de un vector “x” extrayéndolos con reemplazo o sin reemplazo. Ésta es extremadamente útil
para la aleatorización en diseños de experimentos, en simulación y en pruebas de hipótesis.
Veamos un ejemplo:

Sea “y” un vector numérico cualquiera, el cual queremos extraer una muestra o varias de ellas,
bajo diferentes condiciones.

y=c(8,3,5,7,6,6,8,9,2,3,9,4,10,4,11)
y
## [1] 8 3 5 7 6 6 8 9 2 3 9 4 10 4 11

x1=sample(y)
x1
## [1] 8 2 9 3 9 6 7 11 8 5 4 10 4 3 6

x2=sample(y)
x2
## [1] 4 3 5 2 6 9 9 6 8 4 7 8 3 10 11

x3=sample(y)
x3
## [1] 2 4 11 9 9 6 7 3 3 4 5 8 6 10 8
33

Los anteriores ejemplos fueron invocados considerando que han sido extraídos sin reemplazo.
Ahora, podemos especificar el tamaño de la muestra que deseemos como segunda opción dentro
de sus argumentos, es decir:

args(sample)
## function (x, size, replace = FALSE, prob = NULL)
## NULL

y=c(8,3,5,7,6,6,8,9,2,3,9,4,10,4,11)

x4=sample(y,30)
## Error in sample.int(length(x), size, replace, prob) : cannot take a sample larger than the
population when 'replace = FALSE'

STOP ¿Por qué sale este error? ¿Qué habrá que hacer para corregirlo?

Ahora pensemos en un primer ejemplo de aplicación en donde se realice un experimento al


lanzar una moneda equilibrada una vez:

moneda=c("cara","sello")
sample(moneda,size=1)

## [1] "sello”

Ahora, si deseamos repetir este experimento 100 veces y analizar los resultados resumidos en
una tabla de frecuencias:
sample(moneda,size=100,replace = T)

## [1] "cara" "cara" "cara" "sello" "cara" "cara" "cara" "cara"


## [9] "cara" "cara" "cara" "cara" "cara" "cara" "sello" "sello"
## [17] "sello" "sello" "cara" "cara" "sello" "cara" "cara" "cara"
## [25] "sello" "sello" "cara" "cara" "sello" "cara" "cara" "cara"
## [33] "sello" "sello" "cara" "sello" "sello" "sello" "cara" "cara"
## [41] "cara" "sello" "cara" "cara" "cara" "cara" "sello" "cara"
## [49] "cara" "sello" "sello" "sello" "sello" "cara" "cara" "cara"
## [57] "sello" "sello" "sello" "sello" "sello" "sello" "sello" "sello"
## [65] "cara" "cara" "sello" "cara" "cara" "cara" "sello" "cara"
## [73] "cara" "sello" "sello" "cara" "cara" "cara" "sello" "sello"
## [81] "cara" "cara" "sello" "sello" "cara" "sello" "cara" "sello"
## [89] "sello" "cara" "sello" "cara" "sello" "sello" "cara" "sello"
## [97] "cara" "sello" "cara" "cara"

table(sample(moneda,size=100,replace = T))

##
## cara sello
## 54 46
34

STOP Ahora, un segundo ejemplo sería repetir el experimento anterior asumiendo que dicha
moneda no está equilibrada, ¿Qué habría que cambiar o agregar dentro de la función
sample para que esto sea posible? En esta ocasión sería apropiado agregar una gráfica
para observar sus resultados usando la función barplot.

Un tercer ejemplo mucho más interesante es cuando se emplea a la función sample con el fin de
generar muestras bootstrap. John Fox estadístico canadiense una vez escribió lo siguiente “ La
población es a la muestra como la muestra es la muestra bootstrap”, es decir, que se van a generar
muestras a partir de la muestra. A lo anterior se le conoce comúnmente como técnicas de re-
muestreo, la cual se estudiará más a fondo en el Capítulo 5. Tratemos como por ejemplo estimar
un I.C del 95% para el valor de la verdadera media poblacional de una muestra aleatoria de
distribución normal de tamaño 20 con media 10 y desviación estándar 1.

datos=rnorm(20,10)
quantile(replicate(1000,mean(sample(datos,replace = T))),probs= c(0.025,0.975))

## 2.5% 97.5%
## 9.775729 10.715635

Ahora comparemos los resultados anteriores con la técnica tradicional para estimar parámetros
mediante I.C con distribución t de Student.
t.test(datos)

##
## One Sample t-test
##
## data: datos
## t = 40.72, df = 19, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## 9.686177 10.735876
## sample estimates:
## mean of x
## 10.21103

Por lo tanto, como podemos observar, los resultados son muy cercanos entre sí,
confirmando la robustez de la técnica.
34
1.5. MATRICES EN R

1.5.1. Las matrices y sus operaciones

Existen diferentes formas de crear o generar una matriz. Podemos crear uno directamente
utilizando la función matrix de la siguiente manera:

Veamos primero sus argumentos para invocación:

args(matrix)
## function (data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL)
## NULL

Ejemplo # 1:
A=matrix(c(1,2,3,4,5,6,7,8,9),nrow=3)
A
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9

Observación: como pueden notar los valores fueron entrados en dirección columna.

Ejemplo # 2:
I=matrix(c(1,0,0,0,1,0,0,0,1),nrow=3)
I

## [,1] [,2] [,3]


## [1,] 1 0 0
## [2,] 0 1 0
## [3,] 0 0 1

Ahora del ejemplo # 2, se desea verificar que el objeto "I" es una matriz y que su dimensión es de
3 x 3, empleamos las funciones class y attributes respectivamente:
class(I)
## [1] "matrix"

attributes(I)
## $dim
## [1] 3 3
35

Ahora veamos otro ejemplo, en el cual los elementos de la matriz fueron entrados en dirección
fila. Para ello se incluye el argumento byrow=T.
vector=c(1,2,3,4,4,3,2,1)
V=matrix(vector,byrow=T,nrow=2)
V

## [,1] [,2] [,3] [,4]


## [1,] 1 2 3 4
## [2,] 4 3 2 1

Una manera de transformar un vector en una matrix es utilizando la función "dim" es decir:
vector
## [1] 1 2 3 4 4 3 2 1

dim(vector)=c(4,2)
vector

## [,1] [,2]
## [1,] 1 4
## [2,] 2 3
## [3,] 3 2
## [4,] 4 1

dim(vector)=c(2,4)
vector

## [,1] [,2] [,3] [,4]


## [1,] 1 3 4 2
## [2,] 2 4 3 1

Ahora si deseáramos calcular la transpuesta de la matriz anterior, se emplea la función "t":


t.vector=t(vector)
t.vector

## [,1] [,2]
## [1,] 1 2
## [2,] 3 4
## [3,] 4 3
## [4,] 2 1
36

1.5.2. Etiquetando las filas y columnas de una matriz

Sea X una matriz de 4 x 5 de enteros aleatorios de una distribución de Poisson con media 2. Además,
supóngase que las filas se refieren a cuatro ensayos distintos de un experimento que se está realizando.
Para hacer esto posible se utiliza la función rownames. La ventaja de utilizar rownames es que dentro
de sus argumentos se encuentra la opción prefix, la cual reduce el tiempo de trabajo.
X = matrix(rpois(20,2),nrow=4)
X

## [,1] [,2] [,3] [,4] [,5]


## [1,] 4 4 1 2 0
## [2,] 3 4 2 7 1
## [3,] 1 2 2 0 2
## [4,] 2 1 2 2 3

rownames(X) = rownames(X, prefix="Ensayo.")

X
## [,1] [,2] [,3] [,4] [,5]
## Ensayo.1 4 4 1 2 0
## Ensayo.2 3 4 2 7 1
## Ensayo.3 1 2 2 0 2
## Ensayo.4 2 1 2 2 3

Adicionalmente se supondrá que los cuatro ensayos se realizaron bajo cinco drogas distintas
(Dolex, Ibuprofeno, Advil, Noraver y Distran) para tratar el malestar general.
nombre.droga=c("Dolex", "Ibuprofeno", "Advil", "Noraver", "Dristan")
colnames(X)=nombre.droga
X

## Dolex Ibuprofeno Advil Noraver Dristan


## Ensayo.1 4 4 1 2 0
## Ensayo.2 3 4 2 7 1
## Ensayo.3 1 2 2 0 2
## Ensayo.4 2 1 2 2 3

Otra forma de darle nombre a las columnas es con la función dimnames. Suponiendo ahora que
solo queremos especificar el nombre de las columnas, por ejemplo droga 1, 2,..,5, entonces:
dimnames(X) = list(NULL,paste("droga.",1:5,sep=""))
X

## droga.1 droga.2 droga.3 droga.4 droga.5


## [1,] 4 4 1 2 0
## [2,] 3 4 2 7 1
## [3,] 1 2 2 0 2
## [4,] 2 1 2 2 3
37

1.5.3. Cálculos sobre filas y columnas de matrices

Una de las grandes virtudes de R es poder manipular los objetos y hacer operaciones dentro de ellos,
las matrices no es la excepción. Veamos solo algunos ejemplos:

mean(X[,5])
## [1] 2.25

var(X[4,])
## [1] 1.3

rowSums(X)
## [1] 13 12 12 8

colSums(X)
## [1] 14 6 5 11 9

rowMeans(X)
## [1] 2.6 2.4 2.4 1.6

colMeans(X)
## [1] 3.50 1.50 1.25 2.75 2.25

1.5.4. Operaciones básicas


Dada las siguientes matrices A y B de orden 2, realicemos sobre ellas las diferentes operaciones que
puedan producirse, tales como la suma, la resta, la multiplicación, el determinante, la inversa y la
descomposición espectral de una matriz.

A=c(2,6,7,9)
dim(A)=c(2,2)
A

## [,1] [,2]
## [1,] 2 7
## [2,] 6 9

B=c(1,2,3,8)
dim(B)=c(2,2)
B

## [,1] [,2]
## [1,] 1 3
## [2,] 2 8
38

1.5.5. Suma y resta de matrices


Para la suma o resta de matrices se emplea el símbolo correspondiente a tal operador.

C=A+B
C
## [,1] [,2]
## [1,] 3 10
## [2,] 8 17

C=A-B
C

## [,1] [,2]
## [1,] 1 4
## [2,] 4 1

1.5.6. Multiplicación de matrices


Para la multiplicación de matrices se utiliza el operador “%*%”:

C=A%*%B
C

## [,1] [,2]
## [1,] 16 62
## [2,] 24 90

1.5.7. Determinante de una matriz


Para encontrar el determinante de la matriz A o B, utilizamos la función det.

A=c(2,6,7,9)
B=c(1,2,3,8)
A=matrix(A,2,2)
B=matrix(B,2,2)
det(A)
## [1] -24

det(B)
## [1] 2
39

1.5.8. Inversa de matrices


Para encontrar la inversa de la matriz A o B, el lenguaje R no posee un operador interno que realice
dicho cálculo. Lo que habría que hacer es crear una función para tal fin. Afortunadamente existe ya
una función que realiza ese cálculo dentro de un paquete en específico, ésta se llama ginv.

STOP ¿Cómo puedo saber cuál es paquete que contiene dicha función? Investigue

A=c(2,6,7,9)
B=c(1,2,3,8)
A=matrix(A,2,2)
B=matrix(B,2,2)
library(MASS)
ginv
## function (X, tol = sqrt(.Machine$double.eps))
## {
## if (length(dim(X)) > 2L || !(is.numeric(X) || is.complex(X)))
## stop("'X' must be a numeric or complex matrix")
## if (!is.matrix(X))
## X <- as.matrix(X)
## Xsvd <- svd(X)
## if (is.complex(X))
## Xsvd$u <- Conj(Xsvd$u)
## Positive <- Xsvd$d > max(tol * Xsvd$d[1L], 0)
## if (all(Positive))
## Xsvd$v %*% (1/Xsvd$d * t(Xsvd$u))
## else if (!any(Positive))
## array(0, dim(X)[2L:1L])
## else Xsvd$v[, Positive, drop = FALSE] %*% ((1/Xsvd$d[Positive]) *
## t(Xsvd$u[, Positive, drop = FALSE]))
## }
## <bytecode: 0x0000000013bbcfc8>
## <environment: namespace:MASS>

ginv(A)
## [,1] [,2]
## [1,] -0.375 0.29166667
## [2,] 0.250 -0.08333333

ginv(B)
## [,1] [,2]
## [1,] 4 -1.5
## [2,] -1 0.5

STOP ¿Estamos seguros de estos resultados?, compruébenlo manualmente, por ejemplo,


con una matriz A de orden 2.
40

1.5.9. Descomposición espectral de una matriz


Para calcular los valores y vectores propios de una matriz, se emplea la función eigen par tal fin.
De las matrices A y B tenemos que:

A=c(2,6,7,9)
B=c(1,2,3,8)
A=matrix(A,2,2)
B=matrix(B,2,2)
eigen(A)
## $values
## [1] 12.86546 -1.86546
##
## $vectors
## [,1] [,2]
## [1,] -0.5415819 -0.8753983
## [2,] -0.8406480 0.4834024

eigen(B)
## $values
## [1] 8.7720019 0.2279981
##
## $vectors
## [,1] [,2]
## [1,] -0.3601048 -0.9684483
## [2,] -0.9329118 0.2492146
41

1.5.10. Las funciones rbind y cbind

Estas dos funciones son muy útiles al querer agregar ya sea una fila o una columna adicional a una
matriz previamente creada. La función rbind agrega vectores fila a la matriz y la función cbind agrega
vectores columna a la matriz. Veamos algunos ejemplos:

Dadas las matrices A y B anteriores, las cuales están definidas así:

A=c(2,6,7,9)
B=c(1,2,3,8)
A=matrix(A,2,2)
B=matrix(B,2,2)

Para agregar un vector fila a la matriz A y un vector columna a la matriz B, hacemos lo siguiente:
a1=matrix(c(10,13),1,2)
a1

## [,1] [,2]
## [1,] 10 13

A=rbind(A,a1)
A

## [,1] [,2]
## [1,] 2 7
## [2,] 6 9
## [3,] 10 13

b1=matrix(c(10,13),2,1)
b1

## [,1]
## [1,] 10
## [2,] 13

B=cbind(B,b1)
B

## [,1] [,2] [,3]


## [1,] 1 3 10
## [2,] 2 8 13
42

Una utilidad de esta función es al momento de hacer tablas de contingencia, en el cual podemos
agregarle los vectores suma tanto en fila como en columna. Realicemos un ejemplo con la matriz
A.
A=rbind(A,apply(A,2,sum))
A

## [,1] [,2]
## [1,] 2 7
## [2,] 6 9
## [3,] 10 13
## [4,] 18 29

A=cbind(A,apply(A,1,sum))
A

## [,1] [,2] [,3]


## [1,] 2 7 9
## [2,] 6 9 15
## [3,] 10 13 23
## [4,] 18 29 47

rownames(A)<-c(1:3,"Total")
colnames(A)<-c(1:2,"Total")
A

## 1 2 Total
## 1 2 7 9
## 2 6 9 15
## 3 10 13 23
## Total 18 29 47
43

1.5.11. Matriz diagonal

La matriz diagonal más importante que se emplea en el cálculo de matrices es la matriz identidad. Esta
matriz se puede crear mediante la función diag. Por ejemplo si quiero crear una matriz identidad de
orden 4, tenemos que:

K =diag(c(1,1,1,1))
K

## [,1] [,2] [,3] [,4]


## [1,] 1 0 0 0
## [2,] 0 1 0 0
## [3,] 0 0 1 0
## [4,] 0 0 0 1

La anterior la podemos cambiar a una matriz de ceros así:


diag(K)=c(0,0,0,0)
K

## [,1] [,2] [,3] [,4]


## [1,] 0 0 0 0
## [2,] 0 0 0 0
## [3,] 0 0 0 0
## [4,] 0 0 0 0

Una manera de extraer el vector diagonal de una matriz,


vector=diag(K)
vector

## [1] 0 0 0 0
44

1.5.12. Aplicación estadística usando matrices


[Un problema de Análisis Multivariante]. Se ha observado, después de varios estudios en niños de
alrededor de dos años de edad, que la estatura (X1), la longitud toráxica (X2) y la circunferencia media
del antebrazo (X3), tienen aproximadamente una distribución normal. Las siguientes mediciones fueron
realizadas en seis de estos niños, la tabla de abajo contiene los datos (tomados de Chatfield y Collins
1986, pág. 116).
Niño Estatura Toráx Antebrazo
X1 (cm) X2 (cm) X3 (cm)
1 78 60.6 16.5
2 76 58.1 12.5
3 92 63.2 14.5
4 81 59.0 14.0
5 81 60.8 15.5
6 84 59.5 14.0

El objetivo del problema anterior es comprobar la hipótesis Ho : 𝜇´ = (90,58,16).


A un nivel de significancia del 1%.

Se sabe además que la matriz de covarianzas del vector es

29.64 8.59 0.38


Σ = ( 8.59 3.47 1.22)
0.38 1.22 2.04

Connotación: Para verificar la hipótesis 𝐻0: 𝜇 = 𝜇𝑜 de donde 𝜇𝑜 es un vector específico, se


usa como región crítica el conjunto de puntos tales que:

𝜒2 = 𝑛(𝑥̅ − 𝜇 )´Σ−1(𝑥̅ − 𝜇 ) ≥ 𝜒2

Donde 𝜒2 , es 𝜒2(𝑝) > 𝜒(𝛼,𝑝)


el número tal que 𝑃 ( 2

p: Son los grados de libertad (No. De variables) y nivel de significancia.

Así, una muestra que cumpla la desigualdad anterior, provoca el rechazo de la


hipótesis 𝐻0: 𝜇 = 𝜇𝑜

Además, téngase en cuenta que la expresión (𝜇1 − 𝜇2)´Σ−1(𝜇1 − 𝜇2)


es la distancia de Mahalanobis o medida de discrepancia entre el vector de medias
muestral y el vector de medias poblacional; con la expresión anterior se busca
detectar la existencia de posibles diferencias entre el vector de medias muestral y
el vector de medias supuesto.

Tomado y adaptado del libro Estadística Multivariada: Inferencia y Métodos de Díaz, Luis G;
Morales, Mario A.
45

Rutina:

datos=c(78,76,92,81,81,84,60.6,58.1,63.2,59.0,60.8,59.5,16.5,12.5,14.5,14.0,15.5,14.0)
N=matrix(datos,6,3); N
niños=data.frame(N)
colnames(niños)=c("X1","X2","X3"); niños
p=ncol(niños); p # grados de libertad (No. de variables)
n=nrow(niños); n # número de niños
VM=colMeans(niños); VM #vector de medias
miu=c(90,58,16)
PF=t(VM-miu);PF # traspuesta primer factor de la expresión.
MCOV= matrix(c(29.64,8.59,0.38,8.59,3.47,1.22,0.38,1.22,2.04),3,3);MCOV # matriz de covarianzas
IMCOV=ginv(MCOV);IMCOV # inversa de la matriz de covarianza.
TF=t(t(VM-miu));TF # matriz tercer factor de la expresión.
chi.calc=n*PF%*%IMCOV%*%TF;chi.calc # valor estadístico de prueba
chi.tabla=qchisq(0.99,3);chi.tabla #valor estadístico tabla

Conclusión:

De la salida anterior se obtiene que el valor del estadístico de prueba chi-cuadrado es de 464.574 y es
mayor que el de la tabla con 11.34, por lo que se rechaza la hipótesis nula, a un nivel de significancia
del 1%, de donde se concluye que hay una evidencia fuerte contra la hipótesis de que las medias de
estatura, longitud toráxica y la circunferencia del antebrazo son, respectivamente iguales a 90, 58 y 16.
46

1.6 Tabla de datos (Dataframes)


¡Advertencia! Para leer un conjunto de datos en R que se encuentre fuera de su entorno, por ejemplo
que este ubicado en el disco local (C:) se puede usar la función read.table() para su lectura. Sin
embargo existen otras funciones y argumentos dentro de estas para su invocación según el tipo de
datos con el que se está trabajando (numéricos, de caracteres, lógicos, entre otros) y la extensión del
mismo (.csv, .txt, .xlsx, .sav, entre otros). Para saber cómo utilizar cada uno de ellos, haga clic aquí para
seguir vínculo.

Un dataframe es una tabla de datos cuyos componentes (objetos) pueden ser vectores, matrices o
factores. Una forma de crearlos es mediante la función data.frame(). Veamos un pequeño ejemplo:
Familia=c("Padre","Madre","Hijo","Hija")
m=cbind(Orden=1:4,Edad=c(34,36,3,2))
Estatura= c(166,162,101,90)
tabla.familia=data.frame(Familia,m,Estatura)
tabla.familia

## Familia Orden Edad Estatura


## 1 Padre 1 34 166
## 2 Madre 2 36 162
## 3 Hijo 3 3 101
## 4 Hija 4 2 90

1.6.1. Importando dataframes y análisis numérico


Uno de los temas más importantes que hay que dominar en el lenguaje R, es saber entrar, modificar e
invocar una tabla de datos. En R esto se conoce como dataframes. Un dataframe es un objeto con filas
y columnas. Las filas contienen diferentes observaciones del estudio, o medidas del experimento. Las
columnas contienen los valores de las diferentes variables de estudio. Veamos un ejemplo de una tabla
de datos, la cual se encuentra fuera del entorno de R, esta tabla de datos trabaja sobre un estudio a
lombrices en diferentes condiciones ambientales y de terreno. Invoquemos tal archivo mediante la
función read.table, de la siguiente manera:

lombrices=read.table("C:\\Users\\user\\Desktop\\worms.txt",header=T)
lombrices

## Field.Name Area Slope Vegetation Soil.pH Damp Worm.density


## 1 Nashs.Field 3.6 11 Grassland 4.1 FALSE 4
## 2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
## 3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
## 4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
## 5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
## 6 Oak.Mead 3.1 2 Grassland 3.9 FALSE 2
## 7 Church.Field 3.5 3 Grassland 4.2 FALSE 3
## 8 Ashurst 2.1 0 Arable 4.8 FALSE 4
## 9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
## 10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
47

## 11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8


## 12 North.Gravel 3.3 1 Grassland 4.1 FALSE 1
## 13 South.Gravel 3.7 2 Grassland 4.0 FALSE 2
## 14 Observatory.Ridge 1.8 6 Grassland 3.8 FALSE 0
## 15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
## 16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
## 17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
## 18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
## 19 Gravel.Pit 2.9 1 Grassland 3.5 FALSE 1
## 20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3

Nota: Siempre que un conjunto de datos haya sido importando a R, con frecuencia se deben hacer una
cosa: Usar la función “attach” para hacer que la variables estén accesibles por nombre. Además,
recordemos que podemos utilizar la función names para saber las variables que están bajoestudio.

attach(lombrices)
names(lombrices)

## [1] "Field.Name" "Area" "Slope" "Vegetation"


## [5] "Soil.pH" "Damp" "Worm.density"

En primera instancia podemos conocer el resumen de los cinco números (valor mínimo, primer
cuartil, segundo cuartil, tercer cuartil, valor máximo) de cada una de las variables mediante la función
summary, es decir:

summary(lombrices)

## Field.Name Area Slope Vegetation


## Ashurst : 1 Min. :0.800 Min. : 0.00 Arable 3
## Cheapside : 1 1st Qu.:2.175 1st Qu.: 0.75 Grassland:9
## Church.Field: 1 Median :3.000 Median : 2.00 Meadow 3
## Farm.Wood : 1 Mean :2.990 Mean : 3.50 Orchard 1
## Garden.Wood : 1 3rd Qu.:3.725 3rd Qu.: 5.25 Scrub 4
## Gravel.Pit : 1 Max. :5.100 Max. :11.00
## (Other) 14

## Soil.pH Damp Worm.density


## Min. :3.500 Mode :logical Min. :0.00
## 1st Qu.:4.100 FALSE:14 1st Qu.:2.00
## Median :4.600 TRUE :6 Median :4.00
## Mean :4.555 NA's :0 Mean :4.35
## 3rd Qu.:5.000 3rd Qu.:6.25
## Max. :5.700 Max. :9.00
##
48

1.6.2. Subscritos e índices para Dataframe

Recordemos que cuando queríamos extraer un elemento de un vector escribíamos: nombre del vector
[posición]. Ahora para extraer un elemento o un conjunto de ellos de una tabla de datos o dataframe,
escribimos: nombre del vector [posición fila, posición columna].

Veamos y analicemos la salida de algunos ejemplos aplicados a “worms”:

lombrices [3,6]

## [1] FALSE

lombrices [14:19,7]

## [1] 0 6 8 4 5 1

lombrices [1:5,2:3]

## Area Slope
## 1 3.6 11
## 2 5.1 2
## 3 2.8 3
## 4 2.4 5
## 5 3.8 0

lombrices [2,]

## Field.Name Area Slope Vegetation Soil.pH Damp Worm.density


## 2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7

lombrices [,2]

## [1] 3.6 5.1 2.8 2.4 3.8 3.1 3.5 2.1 1.9 1.5 2.9 3.3 3.7 1.8 4.1 3.9 2.2
## [18] 4.4 2.9 0.8

¿Será que lombrices[2,] y lombrices[,2] son iguales?¿cómo puedo averiguarlo?


49

Si quisiera crear un conjunto de filas o de columnas. Por ejemplo extraer todas las filas para Field
Names y Soil pH (columna 1 y 5) usamos la función concatenar c para hacer un vector del número de
las columnas requeridas c(1,5):

lombrices[,c(1,5)]

## Field.Name Soil.pH
## 1 Nashs.Field 4.1
## 2 Silwood.Bottom 5.2
## 3 Nursery.Field 4.3
## 4 Rush.Meadow 4.9
## 5 Gunness.Thicket 4.2
## 6 Oak.Mead 3.9
## 7 Church.Field 4.2
## 8 Ashurst 4.8
## 9 The.Orchard 5.7
## 10 Rookery.Slope 5.0
## 11 Garden.Wood 5.2
## 12 North.Gravel 4.1
## 13 South.Gravel 4.0
## 14 Observatory.Ridge 3.8
## 15 Pond.Field 5.0
## 16 Water.Meadow 4.9
## 17 Cheapside 4.7
## 18 Pound.Hill 4.5
## 19 Gravel.Pit 3.5
## 20 Farm.Wood 5.1
50

1.6.3. Ordenando Dataframes

Es muy común ordenar una tabla de datos por filas, caso contrario para las columnas. Si el objetivo es
ordenar los datos por filas, especificamos la función order en el primer subscrito. Por ejemplo si
deseamos ordenar de menor a mayor la variable “Slope”, se escribe en el prompt, lo siguiente:

lombrices[order(Slope),]

## Field.Name Area Slope Vegetation Soil.pH Damp Worm.density


## 5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
## 8 Ashurst 2.1 0 Arable 4.8 FALSE 4
## 9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
## 15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
## 16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
## 12 North.Gravel 3.3 1 Grassland 4.1 FALSE 1
## 19 Gravel.Pit 2.9 1 Grassland 3.5 FALSE 1
## 2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
## 6 Oak.Mead 3.1 2 Grassland 3.9 FALSE 2
## 13 South.Gravel 3.7 2 Grassland 4.0 FALSE 2
## 18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
## 3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
## 7 Church.Field 3.5 3 Grassland 4.2 FALSE 3
## 10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
## 4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
## 14 Observatory.Ridge 1.8 6 Grassland 3.8 FALSE 0
## 17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
## 11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8
## 20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
## 1 Nashs.Field 3.6 11 Grassland 4.1 FALSE 4

¿Qué hace R si quisiéramos ordenar más de una variable al mismo tiempo, por ejemplo
escojamos “Vegetation” y “Worm.density”?
51

Este es el comando de entrada:

lombrices[order(Vegetation,Worm.density),]

## Field.Name Area Slope Vegetation Soil.pH Damp Worm.density


## 8 Ashurst 2.1 0 Arable 4.8 FALSE 4
## 18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
## 2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
## 14 Observatory.Ridge 1.8 6 Grassland 3.8 FALSE 0
## 12 North.Gravel 3.3 1 Grassland 4.1 FALSE 1
## 19 Gravel.Pit 2.9 1 Grassland 3.5 FALSE 1
## 3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
## 6 Oak.Mead 3.1 2 Grassland 3.9 FALSE 2
## 13 South.Gravel 3.7 2 Grassland 4.0 FALSE 2
## 7 Church.Field 3.5 3 Grassland 4.2 FALSE 3
## 1 Nashs.Field 3.6 11 Grassland 4.1 FALSE 4
## 10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
## 4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
## 15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
## 16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
## 9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
## 20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
## 17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
## 5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
## 11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8

1.6.4. Usando condicionales lógicos para seleccionar filas de una tabla de


datos

Dado el caso en que la tabla de datos contenga una variable con condicionales lógicos, es posible
seleccionar o extraer dichas filas que contenga tal condicional, ya sea TRUE o FALSE. Es decir:

lombrices[Damp == T,]

## Field.Name Area Slope Vegetation Soil.pH Damp Worm.density


## 4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
## 10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
## 15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
## 16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
## 17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
## 20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
52

1.6.5. Otra clase de extracciones para una tabla de datos


o Como se puede observar en el “dataframe” de “worms” hay tres tipos de variables: numéricas,
de caracteres y lógicas. Mediante la función sapply podremos extraer cada una de ellas por
separado.

lombrices[sapply(lombrices,is.numeric)]

## Area Slope Soil.pH Worm.density


## 1 3.6 11 4.1 4
## 2 5.1 2 5.2 7
## 3 2.8 3 4.3 2
## 4 2.4 5 4.9 5
## 5 3.8 0 4.2 6
## 6 3.1 2 3.9 2
## 7 3.5 3 4.2 3
## 8 2.1 0 4.8 4
## 9 1.9 0 5.7 9
## 10 1.5 4 5.0 7
## 11 2.9 10 5.2 8
## 12 3.3 1 4.1 1
## 13 3.7 2 4.0 2
## 14 1.8 6 3.8 0
## 15 4.1 0 5.0 6
## 16 3.9 0 4.9 8
## 17 2.2 8 4.7 4
## 18 4.4 2 4.5 5
## 19 2.9 1 3.5 1
## 20 0.8 10 5.1 3

lombrices[sapply(lombrices,is.factor)]

## Field.Name Vegetation
## 1 Nashs.Field Grassland
## 2 Silwood.Bottom Arable
## 3 Nursery.Field Grassland
## 4 Rush.Meadow Meadow
## 5 Gunness.Thicket Scrub
## 6 Oak.Mead Grassland
## 7 Church.Field Grassland
## 8 Ashurst Arable
## 9 The.Orchard Orchard
## 10 Rookery.Slope Grassland
## 11 Garden.Wood Scrub
## 12 North.Gravel Grassland
## 13 South.Gravel Grassland
## 14 Observatory.Ridge Grassland
## 15 Pond.Field Meadow
## 16 Water.Meadow Meadow
## 17 Cheapside Scrub
## 18 Pound.Hill Arable
## 19 Gravel.Pit Grassland
## 20 Farm.Wood Scrub
53

lombrices[sapply(lombrices,is.logical)]

## Damp
## 1 FALSE
## 2 FALSE
## 3 FALSE
## 4 TRUE
## 5 FALSE
## 6 FALSE
## 7 FALSE
## 8 FALSE
## 9 FALSE
## 10 TRUE
## 11 FALSE
## 12 FALSE
## 13 FALSE
## 14 FALSE
## 15 TRUE
## 16 TRUE
## 17 TRUE
## 18 FALSE
## 19 FALSE
## 20 TRUE

o Otra forma de extracción es utilizando los subscritos negativos.

¿De qué manera podría hacer uso de ellos para obtener los mismos resultados que en
lombrices[sapply(lombrices,is.numeric)] ?

o Ahora si por ejemplo quisiéramos remover todas las filas que contengan “Grassland” de la
variable “Vegetation”, se emplea el símbolo lógico ! que significa NO.

lombrices[!(Vegetation=="Grassland"),]

## Field.Name Area Slope Vegetation Soil.pH Damp Worm.density


## 2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
## 4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
## 5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
## 8 Ashurst 2.1 0 Arable 4.8 FALSE 4
## 9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
## 11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8
## 15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
## 16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
## 17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
## 18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
## 20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
54

1.6.6. Omitiendo filas que contengas valores faltantes, NA


En la modelación estadística a menudo es útil tener una tabla de datos que no contenga valores
faltantes en la respuesta o variables explicativas. Podemos crear una tabla de datos más corto usando
la función na.omit. Esta es una tabla de datos hermano de los worms en el cual ciertos datos son NA.

faltante=read.table("C:/Users/user/Desktop/worms.missing.txt",header=T)
faltante

## Field.Name Area Slope Vegetation Soil.pH Damp Worm.density


## 1 Nashs.Field 3.6 11 Grassland 4.1 FALSE 4
## 2 Silwood.Bottom 5.1 NA Arable 5.2 FALSE 7
## 3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
## 4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
## 5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
## 6 Oak.Mead 3.1 2 Grassland 3.9 FALSE 2
## 7 Church.Field 3.5 3 Grassland NA NA NA
## 8 Ashurst 2.1 0 Arable 4.8 FALSE 4
## 9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
## 10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
## 11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8
## 12 North.Gravel 3.3 1 Grassland 4.1 FALSE 1
## 13 South.Gravel 3.7 2 Grassland 4.0 FALSE 2
## 14 Observatory.Ridge 1.8 6 Grassland 3.8 FALSE 0
## 15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
## 16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
## 17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
## 18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
## 19 Gravel.Pit NA 1 Grassland 3.5 FALSE 1
## 20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3

nuevo=na.omit(faltante)
nuevo

## Field.Name Area Slope Vegetation Soil.pH Damp Worm.density


## 1 Nashs.Field 3.6 11 Grassland 4.1 FALSE 4
## 3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
## 4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
## 5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
## 6 Oak.Mead 3.1 2 Grassland 3.9 FALSE 2
## 8 Ashurst 2.1 0 Arable 4.8 FALSE 4
## 9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
## 10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
## 11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8
## 12 North.Gravel 3.3 1 Grassland 4.1 FALSE 1
## 13 South.Gravel 3.7 2 Grassland 4.0 FALSE 2
## 14 Observatory.Ridge 1.8 6 Grassland 3.8 FALSE 0
## 15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
## 16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
## 17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
## 18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
## 20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
55

1.6.7. Creando una tabla de datos (Dataframes)

Nosotros hemos visto que el medio más simple para obtener una tabla de datos en R es invocándola de
un archivo externo usando la función read.table. Alternativamente, se puede crear un dataframe
usando la función data.frame para unir un número de objetos. Veamos un ejemplo de tres vectores con
la misma longitud:

x=runif(10)
y=letters[1:10]
z=sample(c(rep(T,5),rep(F,5)))

Ahora hagamos que estos tres vectores se conviertan en una tabla de datos:
nuevo=data.frame(y,z,x)
nuevo

## y z x
## 1 a TRUE 0.46784774
## 2 b TRUE 0.57841821
## 3 c TRUE 0.26647084
## 4 d FALSE 0.17227043
## 5 e FALSE 0.97480179
## 6 f TRUE 0.93825077
## 7 g FALSE 0.41372669
## 8 h TRUE 0.52021956
## 9 i FALSE 0.08989702
## 10 j FALSE 0.47717310

Veamos otro ejemplo:

Supongamos que creamos una tabla de frecuencias de enteros aleatorios de una distribución de
Poisson, entonces el objetivo es convertir dicha tabla de frecuencia en una tabla de datos. En primera
instancia hagamos un objeto tabla:

y=rpois(1500,1.5)
frec.t=table(y)
frec.t
## y
## 0 1 2 3 4 5 7 8
## 340 522 352 189 78 15 3 1

Ahora para llevar esta tabla a un "dataframe", escribimos en el prompt lo siguiente:


as.data.frame(table(y))

## y Freq
## 1 0 340
## 2 1 522
## 3 2 352
## 4 3 189
## 5 4 78
## 6 5 15
56

## 7 7 3
## 8 8 1

1.6.8. Usando la función match en dataframes


La tabla de datos “worms” contiene los cinco diferentes tipos de vegetación:

lombrices$Vegetation

## [1] Grassland Arable Grassland Meadow Scrub Grassland Grassland ##


[8] Arable Orchard Grassland Scrub Grassland Grassland Grassland ##
[15] Meadow Meadow Scrub Arable Grassland Scrub
## Levels: Arable Grassland Meadow Orchard Scrub

unique(lombrices$Vegetation)

## [1] Grassland Arable Meadow Scrub Orchard


## Levels: Arable Grassland Meadow Orchard Scrub

Nosotros queremos saber los herbicidas apropiados para usar en cada uno de los 20 campos en
“worms”. Los herbicidas están en un dataframe separado que contiene los herbicidas recomendados
para un gran conjunto de plantas tipo comunitarias:

herbi=read.table("C:\\Users\\user\\Desktop\\herbicides.txt",header=T)
herbi

## Type Herbicide
## 1 Woodland Fusilade
## 2 Conifer Weedwipe
## 3 Arable Twinspan
## 4 Hill Weedwipe
## 5 Bracken Fusilade
## 6 Scrub Weedwipe
## 7 Grassland Allclear
## 8 Chalk Vanquish
## 9 Meadow Propinol
## 10 Lawn Vanquish
## 11 Orchard Fusilade
## 12 Verge Allclear
57

El resultado de este match es usado como un vector de subscritos para extraer los herbicidas
relevantes de herbi$Herbicides y además agregarlos al dataframe:

union=data.frame(lombrices[,4:7],herbi=herbi$Herbicide[match(lombrices$Vegetation,herbi$
Type)])
union

## Vegetation Soil.pH Damp Worm.density herbi


## 1 Grassland 4.1 FALSE 4 Allclear
## 2 Arable 5.2 FALSE 7 Twinspan
## 3 Grassland 4.3 FALSE 2 Allclear
## 4 Meadow 4.9 TRUE 5 Propinol
## 5 Scrub 4.2 FALSE 6 Weedwipe
## 6 Grassland 3.9 FALSE 2 Allclear
## 7 Grassland 4.2 FALSE 3 Allclear
## 8 Arable 4.8 FALSE 4 Twinspan
## 9 Orchard 5.7 FALSE 9 Fusilade
## 10 Grassland 5.0 TRUE 7 Allclear
## 11 Scrub 5.2 FALSE 8 Weedwipe
## 12 Grassland 4.1 FALSE 1 Allclear
## 13 Grassland 4.0 FALSE 2 Allclear
## 14 Grassland 3.8 FALSE 0 Allclear
## 15 Meadow 5.0 TRUE 6 Propinol
## 16 Meadow 4.9 TRUE 8 Propinol
## 17 Scrub 4.7 TRUE 4 Weedwipe
## 18 Arable 4.5 FALSE 5 Twinspan
## 19 Grassland 3.5 FALSE 1 Allclear
## 20 Scrub 5.1 TRUE 3 Weedwipe
58

1.7. PROGRAMANDO CON R

1.7.1. Motivación

Una de las atracciones principales de usar el lenguaje de programación de R es la facilidad con que los
usuarios pueden escribir sus propios programas y funciones. La sintaxis de programación de R es
sumamente fácil de aprender, incluso para los usuarios sin ningún tipo de experiencia en
programación. Una vez se entienda las estructuras básicas de mando de R, los usuarios pueden usar el
lenguaje como una máquina de cálculos poderoso para realizar análisis complejos de casi cualquier
tipo de datos.

1.7.2. Componentes básicos de un programa

Los programas de los computadores pueden llegar a ser muy complejos, pero, en realidad todos ellos
constan de muy pocos componentes. El aprendizaje de los componentes básicos no es difícil. Esto es
especialmente cierto en R, que es un lenguaje de programación con pocos requerimientos, por lo que
se pueden escribir programas sencillos en poco tiempo.

Cuando se ejecuta un programa es necesario acceder a la memoria interna del procesador. La mayoría
de lenguajes no permiten el acceso directo a dicha memoria, sino que el acceso se hace mediante unas
entidades denominadas variables. Estas variables pueden contener números, caracteres u otras
estructuras más complejas. A lo largo del programa el contenido de una variable puede cambiar de
valor.

Los programas se estructuran en sentencias, las cuales se van ejecutando unas detrás de otras. Las
sentencias pueden ser simples o complejas. Las sentencias complejas constan de varias sentencias
simples.

Para que un programa pueda hacer cosas interesantes es necesario que se le permita bifurcarse.
Normalmente esto se hace mediante la evaluación de una condición lógica. Si ésta es cierta el programa
hace una cosa y si es falsa hace otra cosa distinta.

Los computadores son excelentes haciendo tareas repetitivas. Estas tareas que hay que realizar,
muchas veces se ponen dentro de unas estructuras conocidas como bucles.

A veces nos encontramos dentro de un programa con partes muy parecidas, solo que unas veces se
aplican a unas variables y otras veces a otras. Los lenguajes de programación suelen permitir unas
estructuras (funciones en R) que pueden ser ejecutadas de forma ligeramente distinta dependiendo
de unos parámetros o argumentos que se pasan en el momento de la ejecución.
59

1.7.3. Bibliografìa de apoyo a la programación

Esta es una lista bibliográfica sobre programación en R. Algunos de ellos los pueden adquirir de
manera gratuita en formato pdf y otros tendrían que comprarlos.

A First Course in Statistical Programming with R, por W. John Braun y Duncan J.Murdoch
R Programming for Bioinformatics, por Robert Gentleman
S Programming, por W. N. Venables and B. D. Ripley
Programming with Data, por John M. Chambers
R Help & R Coding Conventions, por Henrik Bengtsson, Lund University
Programming in R, por (Vincent Zoonekynd)
Peter's R Programming Pages, University of Warwick
Rtips, Paul Johnsson, University of Kansas

1.7.4. ¿cómo construir e invocar una función?

Una de las grandes ventajas de trabajar con R es la de disponer de una gran cantidad de funciones
escritas por miles de programadores en todo el mundo y puestas a nuestra disposición en Internet.
Pero no siempre existirá la función que nosotros queramos, por lo que también es conveniente que
sepamos crear nuestras propias funciones.

Tal como hemos notado en la construcción de nuestras primeras funciones, R las trata prácticamente
igual que cualquier otra variable. Así, ellas se pueden manipular de manera semejante como se hace
con otros objetos de R, por ejemplo:

Se pueden pasar como argumentos de otrasfunciones.


 Se pueden regresar como el valor final de unafunción.
 Se pueden definir en el interior de otra función.

Una función se define de la siguiente forma (tal como lo vimos anteriormente):


60

Donde,
 nombre: es una palabra “específica” con que el usuario identifica sufunción.
 function: es una palabra “reservada” que indica que lo que sigue es una función.
 args1, args2, …: es una lista de letras o palabras separadas por comas que contiene los
argumentos que deben estar incluidos dentro del cuerpo de la función . A estos argumentos se
les conoce como argumentos formales, que son los que se proveen al momento de invocar la
función de acuerdo a un valor particular. También se podría establecer de manera numérica
argumentos con valores por omisión o por defecto (Desventaja: pasaría de ser una función
general a específica)
 y cuerpo de la función: es una serie de sentencias o expresiones válidas en R, las cuales se
encuentran incluidas dentro de los símbolos { }.

Una vez definida o construida la función se puede invocar desde nuestro programa de la siguiente
manera:

Otra forma sería asignándole un nombre “cualquiera” a dicha función, dado el caso en que se vaya a
emplear esos resultados en otra función, es decir:

Ejemplo # 1.

Construya una función que permita calcular la hipotenusa o un cateto de un triángulo rectángulo
dado sus otros dos lados.

Desarrollo

Descargar y cargar Script 1 (dentro de la carpeta “Scripts” del Drive) en RStudio:

Enlace:
https://drive.google.com/drive/folders/0B3dFK0R9NddVcFo4T3k4UGM1aDA
61

1.7.5. Notas Importantes para tener en cuenta al momento de crear una


función

a. Tener mucho cuidado con las expresiones de asignación:


 Símbolos de escritura.
 y símbolos de lectura.

b. Tener mucho cuidado en la asignación de cualquier nombre a una función en particular


creada por usted. Puede tener ¡errores de cálculo!, sino tiene en cuenta este detalle. Ver
Ejemplo # 2a y 2b. Script 1.

c. R mantiene por separado los espacios de nombres de las funciones y de todos los otros
objetos que no son funciones. Ver Ejemplo # 2c. Script 1.

1.7.6. Tipos de símbolos en el interior de una función


Para entender esto veamos un pequeño ejemplo:

Ejemplo # 3.

Evalúe la siguiente expresión algebraica 2*(x+y) - k, dado que x=2, y=5, k=3.

k=3
fun=function(x,y){
m=2*(x+y)-k
m
}

Tipología:

 k = variable libre (definida previamente fuera de la función)


x , y = argumentos (formales)
 m = variable local (definida dentro del cuerpo de la función)

Actividades en clase:

Desarrolle las actividades 1, 2, 3 y 4. Ver Script 1.


62

1.7.7. Estructuras de control

En los lenguajes de programación, se entiende por estructuras de control aquellas


construcciones sintácticas del lenguaje que dirigen el flujo de la ejecución de un programa en una
dirección o en otra dentro de su código.

Las diferentes estructuras de control que existe en cualquier lenguaje de programación, así como en
R son:
Estructuras condicionales: if - else, Ifelse y switch.
 Estructuras de repetición definida e indefinida: for, while y repeat.
Otras sentencias: break y next.

Recordemos los diferentes tipos de operadores de comparación y lógicos:

 == (igual)
!= (diferente)
>= (mayor o igual que)
<= (menor o igual que)
& (y)
| (o)
 ! (no o negación)

1.7.7.1. Sentencias: if - else, ifelse yswitch.

a. Las sentencias if - else ( ) Son aquellas que, según el resultado de una comparación, realizan
una u otra acción. Es decir, que permiten ejecutar o saltar un conjunto o bloque de
instrucciones dentro del código de un programa.

Sintaxis

if ( condicional lógico) { Expresión cuando VERDADERO (TRUE) }

if ( condicional lógico) {Expresión cuando VERDADERO (TRUE)}


else {Expresión cuando FALSO (FALSE) }

if ( condicional lógico) {Expresión cuando VERDADERO }


else if ( condicional lógico) {Expresión cuando VERDADERO }
else {Expresión cuando FALSO }
63

Esta declaración constituye un conjunto de órdenes para ser invocado, donde la condición if
evalúa lo VERDADERO. La parte else es opcional, y proporciona un conjunto de comandos
alternativos los cuales serán invocados en caso de que la variable lógica sea FALSA.

La manera conveniente de escribir este comando en el editor de texto sería:

if (condicional.lógico) {
comandos cuando VERDADERO
} else {
Comandos cuando FALSO
}

b. La sentencia ifelse , es la estructura abreviada de if – else.

Sintaxis
ifelse ( condicional lógico, acción en caso cierto, acción en caso falso)

c. La sentencia switch, toma una expresión y devuelve un valor en una lista basada en el valor
de la expresión.

Sintaxis
switch ( expresión, opción1, opción 2, opción 3, …, opción n)  si la expresión es un número.

switch (expresión, “nombre1”=formula1, “nombre2”=formula2, …)  si la expresión es un


Carácter.

1.7.7.2 Aplicaciones basadas en Estructuras Condicionales:

Descargar y cargar Script 2 (dentro de la carpeta “Scripts” del Drive) en RStudio:

Ejemplo # 4

Un problema muy sencillo. Supongamos que deseamos calcular el valor de una función definida a
trozos, de acuerdo a los subdominios establecidos.

x=2
if(x>2) {
y=2*x
} else {
y=3*x
}
Llevando lo anterior a modo de una función sería:
64

# a) Usando la sentencia if - else.

fun.if= function(x) {
if(x>2) {
y=2*x
} else {
y=3*x
}
print(y)
}
fun.if
fun.if(4)
fun.if(-1)

# b) usando la sentencia ifelse.


fun.ifelse=function(x) {
ifelse(x>2,2*x,3*x)
}
fun.ifelse(4)
fun.ifelse(-1)

# c) usando la sentencia switch.

fun.switch=function(x,opcion){
switch(opcion,"mayor"=2*x,"menor"=3*x)
}
fun.switch(x = 4,opcion = "mayor")
fun.switch(-1,"menor")

Ejemplo 5.

La correlación entre dos vectores numéricos se calcula frecuentemente usando la función cor ( ). Este
mide la asociación lineal entre ambos vectores. Además, podemos agregar un gráfico de dispersión de
los datos, si uno lo requiere. La función que permite obtener ambas salidas es:

cor.graf = function(x,y,grafica=F) {

if (grafica == TRUE) {
plot(x, y,col=blue)
}
cor(x, y)
}
Para verificar su funcionamiento, calculemos el coeficiente de correlación de Pearson de las variables
“speed” y “dist” del conjunto de datos “cars”, siendo ésta última la variable dependiente.
65

cor.graf(cars$speed,cars$dist)
cor.graf(cars$speed,cars$dist,T)

------------------------------------------------------------------------------------------------------------------------------
Nota: Para ver más ejemplos de ésta estructura (Ejemplos 6 y 7). Ver Script 2.
--------------------------------------------------------------------------------------------------------------------------------
66

1.7.8. Estructuras de repetición, bucles o loops definidas eindefinidas.


Hay tres tipos de bucles dependiendo de si conocemos de antemano el número de veces que hay que
repetirlo (iteraciones). Si sabemos a priori el número de iteraciones la instrucción en R es for ( ); por
el contrario, si el número de iteraciones depende de los cálculos que se efectúen en el propio bucle la
instrucción adecuada en R es while ( ). De otra manera se puede decir que:

La estructura for asigna a la variable cada uno de los valores y realiza la acción para cada uno. La
estructura while evalúa la condición y mientras esta es cierta se evalúa la acción. La estructura
repeat evalúa la acción indefinidamente. En los tres casos, el valor del ciclo completo es el de la
última evaluación de la acción.

Las expresiones pueden contener algún condicional como if asociado con las funciones next o
break. La estructura next indica que debe terminarse la iteración actual y pasar a la siguiente. La
estructura break indica que debe terminarse el ciclo actual.

1.7.8.1 Sentencia: for

Sintaxis

for ( nombre in vector) { comandos }

1.7.8.2 Sentencia: while

Sintaxis

while ( condición lógica) { comandos }

1.7.8.3 Sentencia: repeat

Sintaxis

repeat { comandos }

if (condición lógica) break


67

Ejemplo # 8

Escribir una función que calcule e imprima los cuadrados de un número, bajo ciertas condiciones:
a) Para enteros entre -5 y 5.
b) Para enteros entres - 5 y 5 sin incluir el 0.
c) Para enteros entre - 5 y 5 hasta que aparezca el 1.
d) Que empiece en 4 pero que sea menor o igual a 10. Usando "while"
e) Que empiece en 4 pero que sea menor o igual a 10. Usando "repeat"...if ()break.

Abajo se muestra solo el cuerpo de la función del punto a).

for (i in -5:5) print(i^2) # ó


for (i in -5:5) {
cat(i,"\t", i^2,"\n")
}

La variable i del bucle anterior se denomina variable de control del bucle. Si analizamos la estructura
vemos que: en el paréntesis que sigue a for se indica el nombre de la variable de control y como debe
variar mediante la instrucción in (entre 1 y 10 en este ejemplo), finalmente mediante la función print
le pedimos que imprima los resultados de acuerdo a la ecuación requerida.

¿Cómo podríamos llevar lo anterior como un objeto tipo función? O escribir una función que
calcule e imprima los cuadrados de los n primeros números naturales. Desarrolle esto en el editor de
RStudio.

Para ver el desarrollo completo del ejemplo ver script 2.


68

Ejemplo # 9

La secuencia de Fibonacci es una secuencia famosa en matemáticas. Los primeros dos elementos son
definidos como [1,1]. Los siguientes elementos son definidos como la suma de los dos elementos
predecesores. Por ejemplo, el tercer elemento es 2 (=1+1), el cuarto elemento es 3 (=1+2), el quinto
elemento es 5(=2+3), y así sucesivamente. De lo anterior, escriba una función que calcule los primeros
12 números de Fibonacci en R.

fib= function() {
Fibo=numeric(12) # la función "numeric" genera un vector de ceros de longitud 12.
Fibo[1]=Fibo[2]=1
for (i in 3:12) {
Fibo[i] = Fibo[i - 2] + Fibo[i - 1]
}
print(Fibo)
}
fib()

Ejemplo 10

Escribir una rutina que imprima todos los números naturales cuyo cubo sea inferior a 100.

i=1
i3 = i^3
while (i3 < 100){

cat(i, i3, "\n")


i=i+1
i3 = i^3
}

Nota: En este caso usamos la función cat para imprimir el resultado en lugar de la función print; cat
permite concatenar el output ("\n" indica salto de línea).

De manera general la sintaxis para escribir el resultado de algún valor dándole un nombre a éste
empleando la función cat sería:

cat(“palabra =”, fórmula, “variable =”, fórmula, “\n”)


69

1.7.7. Programación eficiente

Para escribir códigos de manera eficiente, es necesario entender la plataforma en que se encuentra
uno trabajando. Por ejemplo, R está diseñado para trabajar con vectores. Operaciones sobre vectores
completos son generalmente mucho más rápido que trabajar un elemento a la vez. Por ejemplo, si
quisiéramos crear una función que sumara dos vectores teniendo en cuenta lo anterior se podría hacer
de la siguiente manera:

suma.lenta=function(n) {
X <- rnorm(n)
Y <- rnorm(n)
Z=c()
for(i in 1:n) {
Z[i]= X[i]+Y[i]
}
print(Z)
}

suma.veloz=function(n) {
X <- rnorm(n)
Y <- rnorm(n)
Z=rep(NA,n)
for(i in 1:n) {
Z[i]= X[i]+Y[i]
}
print(Z)
}

Para verificar si realmente las funciones anteriores dan fe a su nombre, podremos usar la función
system.time ( nombre del objeto) y medir el tiempo de ejecución.
70

RETO FINAL
Supongamos que me piden elaborar un programa o rutina que construya una tabla de distribución de
frecuencias agrupada (usando inicialmente “Sturges” para obtener el número de clases) donde se
refleje los límites de clase (inferior y superior), las marcas de clase, la frecuencia absoluta, la frecuencia
acumulada, la frecuencia relativa y frecuencia relativa acumulada. Así como su histograma y el polígono
de frecuencias (ambos en un mismo plano) y la ojiva. Ahora, de su rutina anterior cambie el argumento
“breaks” dentro de la función hist por las fórmulas para obtener el número de clases (número de
barras) desarrolladas por Scott y Freedman- Diaconis, con el fin de comparar sus resultados. En esta
parte para establecer diferencias podría tener en cuenta el tamaño de la muestra (por ejemplo creando
un vector aleatorio de distribución normal de media 20 y desviación estándar 5 redondeado a un lugar
decimal para n=20, n=30, n= 50 y n=100), por otro lado incluya datos atípicos (por ejemplo uno dentro
de cada vector numérico anterior). De todo el análisis previo ¿Cuál de ellos ofrece la forma de
distribución más estable? Justifique todo su análisisestadísticamente.

Pregunta abierta: ¿Por qué después de aproximadamente 90 años los libros de estadística y
profesores de estadística aún siguen empleando “Sturges” en la actualidad?

Algunas razones que un podría plantearse son: ¿Será que los trabajos de Scott y Freedman – Diaconis
no han sido muy aceptados por la comunidad de estadísticos?¿Será que son completamente
desconocidos dentro de nuestra sociedad de estadísticos (Latinoamérica)? ¿Sus algoritmos son más
complejos para su ejecución?

Para un ejemplo en particular, corra su rutina ya sea mediante Sturges, Scott o Freedman - Diaconis
teniendo en cuenta las características de los datos (tamaño de la muestra y/o datos atípicos, si aplica)
de la variable “thickness” del conjunto de datos “Melanoma” de la biblioteca “MASS”.

Formato de trabajo:

[Opción 1]
a) Crear un documento (.txt) donde describa las características principales de surutina.
Por ejemplo vea el siguiente link http://127.0.0.1:19404/library/graphics/html/hist.html
b) Crear un documento (.txt) donde se muestre su rutina desarrolla en R o enRStudio.
c) Diseñar un documento (pdf) donde se evidencie una introducción, una breve descripción del
problema, una parte teórica del trabajo, las salidas de sus resultados con su respectiva
interpretación, las respuestas a las preguntas formuladas, conclusiones generales y referencias
bibliográficas.
d) Compile todo su trabajo en una misma carpeta.

[Opción 2]  Reto # 2.
a) Crear tu propio paquete de R que incluya la(s) función(es) y el conjunto de datos para su
ejecución. Para su construcción siga el siguiente link:
http://www.ub.edu/stat/docencia/Cursos-R/Radvanced/materials/Crear_paquetes_R.pdf
b) Realice de la [Opción 1] inciso c).
71

_____________________________________________________________________________________________

UNIDAD 2

PROGRAMACIÓN DE GRÁFICOS CON R


Basado esencialmente en el libro de Gráficos Estadísticos y Mapas con R.
.
Por Cástor Guisande Gónzalez y Antonio Vaamonde Liste

“Un gráfico puede valer más que mil palabras,


pero puede tomar muchas palabras para hacerlo”
John Tukey

2.1. Motivación

Los estadísticos han utilizado siempre gráficos para mostrar los resultados de forma que pudieran ser
interpretados por diferentes tipos de lectores, incluyendo aquellos con escasos o nulos conocimientos
de estadística. Los gráficos ayudan a entender mejor las conclusiones obtenidas en la aplicación de
diferentes métodos estadísticos, y generalmente se busca con la representación reforzar visualmente
los aspectos más destacables de los datos y losresultados.

Algunos gráficos estadísticos aparecen con frecuencia en la prensa o en los distintos medios de
comunicación, ya que son necesarios para entender mejor la realidad que nos rodea. Un conocimiento
elemental de los gráficos más comunes forma parte hoy en día de la cultura general de los ciudadanos,
y es habitual encontrarlos, junto con otros conceptos estadísticos elementales, en los planes de
estudios de la enseñanza obligatoria de cualquier país moderno.

Existen centenares de tipos distintos de gráficos y múltiples variantes de cada uno de ellos. Los
programas estadísticos generalmente han prestado mucha atención a la construcción de gráficos, que
suelen ser un apartado importante del menú del usuario. A menudo se busca la construcción
automática del gráfico, liberando al usuario de esfuerzo alguno y la incomodidad de definir tamaños,
escalas, líneas colores, leyendas o complementos diversos como sucede con la mayoría de los Software
Estadísticos tales como SPSS, Statgraphics, Minitab, Infostat, entre otros.

Sin embargo R se ha convertido durante la última década en el programa estadístico de uso general
más potente, con mucha diferencia sobre los restantes, y también el más versátil, debido a las grandes
contribuciones que este recibe constantemente, con el fin de proveer trabajos de excelente
72

calidad. Y no faltaba más que la construcción gráfica R se considera el programa estadístico con mayor
capacidad y flexibilidad, pues éste a diferencia de los otros programas, no busca tanto a la rapidez y
comodidad del usuario mediante la construcción automática de un gráfico único y cerrado sino, por el
contrario, la flexibilidad y el control de los distintos elementos del gráfico, que el usuario puede diseñar
a su medida. Este planteamiento, que hace posible obtener gráficos personalizados, obliga por parte a
un mayor esfuerzo de programación y a un mayor nivel de conocimiento, pero el esfuerzo obtiene su
recompensa en un resultado en general mucho más satisfactorio, mostrando gráficos de muy alta
calidad.
73

2.2.1. Primeros pasos.

Las diferentes instrucciones de R para realizar gráficos, que forman parte de los diferentes paquetes,
se pueden dividir en:

 Funciones gráficas. Permite realizar diferentes tipos de gráficos y tienen sus propios
argumentos específicos.

 Complementos gráficos. Son también funciones que permiten añadir a los gráficos líneas,
textos, flechas, leyendas, etiquetas, etc., y también tienen sus propios argumentos específicos.

 Argumentos generales. Son argumentos que se pueden usar en las funciones y complementos
gráficos anteriores, además de los argumentos específicos de cada una deellas.

El siguiente esquema resume la estructura de los paquetes:

Recordemos que cuando se instala un paquete se instala las funciones que contiene y, en muchos
casos, también se instalan datos que se utilizan para ilustrar los ejemplos de uso de las funciones.
Para acceder a una lista completa de todas las funciones dentro de un paquete, tecleamos la siguiente
instrucción:

library (help= "graphics")

Existen demos que nos muestran buenos ejemplos de gráficos con su correspondiente código:

demo(graphics)

demo(image)
74

2.2.2. Colores

Con la función colors( ), que viene en el paquete básico, es posible obtener un listado de los 657
colores disponibles. Abajo muestra la salida de solo una pequeña porción del gran listado:

…………………………………………………………………………………………………………………………………………………

Existen otras funciones fuera de los paquetes básicos que me muestran un sin número de opciones
de paletas de colores. Por ejemplo:

1. La función colorTable ( ) del paquete “fBasics” (Wuertz, 2011) permite ver los números de los
diferentes tipos de colores.

library(fBasics)

colorTable(cex=1)

2. La función show.colors ( ) del paquete “DAAG” (Maindonald, 2011) permite ver los nombres de
los diferentes tipos de colores: “single” son los colores que no tienen diferentes intensidades,
“shades” son los que sí tienen diferentes intensidades y “gray” es para ver la escala de grises.

library(DAAG)

show.colors("singles")

show.colors("shades")

show.colors("gray")
75

3. También son muy útiles las paletas de colores que se pueden obtener con alguna de las funciones
“gray.colors( )”, “rainbow( )”, “heat.colors ( )”, “terrain.colors( )”, “topo.colors ( )” o “cm.colors (
)” del paquete “grDevices”, el cual se instala por defecto con R. A modo de ejemplo visual, las
siguientes instrucciones (Block de Notas) representan un diagrama de tortas, en el cual el
gradiente de colores se realiza con las funciones mencionadas anteriormente.

#Gráfico 1
pie(rep(1,50), col=gray.colors(n=50))
text(0,1,"gray.colors()",font=2,cex=1.5)

#Gráfico 2
pie(rep(1,15), col=rainbow(n=15, s =1, v=1, start=0, end=0.9, alpha=1))
text(0,1,"rainbow()",font=2,cex=1.5)

#Gráfico 3
pie(rep(1,50), col=heat.colors(n=50))
text(0,1,"heat.colors()",font=2,cex=1.5)

#Gráfico 4
pie(rep(1,50), col=terrain.colors(n=50))
text(0,1,"terrain.colors()",font=2,cex=1.5)

#Gráfico 5
pie(rep(1,50), col=topo.colors(n=50))
text(0,1,"topo.colors()",font=2,cex=1.5)

#Gráfico 6
pie(rep(1,50), col=cm.colors(n=50))
text(0,1,"cm.colors()",font=2,cex=1.5)
76

2.2.3. Fórmulas matemáticas y caracteres especiales

En muchas ocasiones a los gráficos hay que añadirles fórmulas matemáticas o textos con caracteres
especiales, que se pueden realizar con la función “plotmath ( )” (Murrell y Ihaka, 2000), combinada con
alguna de las funciones “expression( )”, “substitutes( )” y/o “paste( )”. A continuación se muestra
algunos ejemplos.

Nota: Para que estas instrucciones funcionen deben integrarse en los gráficos las funciones “mtext(
)”, “title( )” o “text( )”.

plot(0,0,type="n",bty="n", xaxt="n", yaxt="n",xlab="",ylab="")

#Texto 1

text(0,0.9,expression(x^2==sum(sum(frac(((O[mc] - E[mc]) - frac(1,2))^2, E[mc]), c-1, i), m-1, j)))

#Texto 2

text(0,0.6,expression(L[t]==L[infinity](1-e^-k(t-t[0]))))

#Texto 3

text(0,0.3,expression(a[i] == sqrt(b[i]^2 + c[i]^2)))

#Texto 4

text(0,0,expression("r"==paste(frac(paste(mu[max]*"S"), paste("K"[s]+"S")))))

#Texto 5

text(0,-0.3,expression(bar(x) == frac(sum(x[i], n, i==1), n)))

#Texto 6

text(0,-0.6,expression(paste("Producción primaria en mg C m"^"-2","d"^"-1")))

#Texto 7

text(0,-0.9,expression(bold(paste("Pigmentos de ", italic("Alexandrium minutum")))))


77

Salida en R:

2.2.4. Dispositivos para gráficos


Una vez creado un gráfico es necesario visualizarlo y, para ello, existen diferentes dispositivos
(devices). El más común, el cual se usa por defecto, es la pantalla y la función que controla este
dispositivo es “Windows( )”. Sin embargo, se puede visualizar el gráfico exportándolo a un archivo, que
puede tener diferentes formatos, y se controlan con alguna de las siguientes funciones: “png( )”,
“bitmap( )”, “jpeg( )”, “bmp( )”, “tiff( )”, “pdf( )”, “postscript( )” e incluso a una impresora “win.print(
)”. Durante el curso de esta unidad estaremos empleando algunas de estas funciones de exportación.
78

2. 3. GRÁFICOS BÁSICOS

2.3.1. Gráficos de dispersión


Se utilizan con mucha frecuencia, y representan dos variables cuantitativas en un sistema de
coordenadas rectangulares.

Ejemplo # 1: se usará el conjunto de datos <<iris>> de la biblioteca “datasets”, y se representarán dos


variables con relación lineal entre ellas: Petal.Lenght (longitud del Pétalo) y Petal.Width (Ancho del
Pétalo). Para el gráfico de dispersión más simple, utilizamos la función “plot( )” sin hacer ningún tipo
de modificaciones a sus argumentos. La función “par(ps=15)” permite definir el tamaño de la letra.

#Carga los datos y los guarda en memoria


data(iris)
attach(iris)
par(ps=15)

#Gráfico de dispersión entre dos variables


plot(Petal.Length,Petal.Width)

Nota: Dentro de la función “plot( )” se pueden incluir varios argumentos que permiten modificar la
apariencia del gráfico de manera personalizada.

Ahora, al gráfico anterior le iremos añadiendo y modificando ciertos elementos, por ejemplo si existen
varios datos en el mismo punto, con la función “sunflowerplot( )” es posible que pinte tantas rayas
como número de datos coinciden en el mismo punto.
79

#Modificación del tipo de símbolos y que se vean los puntos repetidos


sunflowerplot(Petal.Length,Petal.Width,pch=19)

Investiga: para saber sobre los diferentes parámetros empleados en los gráficos y tipo de simbología
que representa cada uno de los puntos del gràfico, se escribe en R lo siguiente:
?points o ?par

Ahora, le podremos rotular los ejes y añadir un título:

#Legenda de los ejes


sunflowerplot(Petal.Length,Petal.Width,pch=19,xlab="Longitud (cm)",ylab="Anchura (cm)")

#Título del gráfico


sunflowerplot(Petal.Length,Petal.Width,pch=19,xlab="Longitud (cm)",ylab="Anchura (cm)",
main="Longitud de pétalo vs Anchura de pétalo")

También se le puede hacer una serie de ajustes en el tipo de letra, como se verá a continuación:

#Cambios en los tipos y tamaños de las letras


sunflowerplot(Petal.Length,Petal.Width,pch=19,xlab="Longitud (cm)",ylab="Anchura (cm)",
main="Longitud de pétalo vs Anchura de pétalo",
font.axis=2,font.lab=2,cex.main=1.5,cex.lab=1.25,family="serif",asp=1.5,
ylim=c(0.5,2.5))

Finalmente, le podremos añadir a este gráfico una recta de regresión con la función “abline( )”.

#Recta de regresión
reg =lm(iris$Petal.Width~iris$Petal.Length)
abline(reg)
80

Actividad en clase: Agreguemos al gráfico el modelo de regresión lineal de mínimos cuadrados. Usa
las funciones coef() y text() y expression() para ello. Además de ir a la ayuda para saber cómo escribir
las diferentes simbología matemáticas en R. ?plotmath

Ejemplo # 2: Usando el mismo conjunto de datos, veremos una situación un poco más complicada. Se
trata de una gráfica similar a la anterior, con la diferencia en la que queremos resaltar diferentes grupos
de datos. Las variables de interés son: Petal.Length y Sepal.Length. La función “locator( )” permite
obtener las coordenadas de cualquier punto que se señale sobre el plano de la gráfica con el ratón y
situar el ángulo superior izquierdo de la leyenda sobre él. El primer argumento de “locator(n)”
establece l número máximo de objetos que se desea ubicar.

data(iris)

attach(iris)

plot(iris[Species=="setosa","Petal.Length"],iris[Species=="setosa","Sepal.Length"],xlim=c(0,9),
ylim =c(3,9),pch=19,col="blue",xlab="",ylab="",bty="l")

points(iris[Species=="virginica","Petal.Length"],iris[Species=="virginica","Sepal.Length"],
pch=19,col="green")

points(iris[Species=="versicolor","Petal.Length"],iris[Species=="versicolor","Sepal.Length"],
pch=21, bg="red")

title(main="Longitud de Pétalo vs Longitud de sépalo",xlab="Longitud de pétalo (cm)",


ylab="Longitud de sépalo (cm)",font.main=2,font.lab=2,cex.main=1.5)

legend(locator(1),c("setosa","virginica","versicolor"),pch=c(19,19,19),col=c("blue","green","red"))
81

Ejemplo # 3: En un gráfico de dispersión es posible incluir una recta de regresión y representar


intervalos de confianza para el valor estimado, o de otro modo el rango de valores dentro del cual debe
estar la predicción de la variable dependiente con una probabilidad determinada. En este ejemplo se
usan datos que se encuentran dentro del archivo “Carangidae.csv”, de la longitud estándar y base de la
aleta dorsal de varias especies de peces de la familia Carangidae. Los datos se muestran a continuación:

Datos = read.csv2("Carangidae.csv", header=TRUE, encoding="latin1")

attach(Datos)

#Cálculo de la regresión
regre = lm(Dorsal~Longitud)
modelo = summary(regre)
modelo

#Cálculo del intervalo de confianza


Conf = predict(regre,interval="confidence",level=0.99)

#Se representan los datos


plot(Longitud,Dorsal,xlim=c(0,700), ylim=c(0,400), xlab="Longitud estándar (mm)", cex.lab=1.6,
font.lab=2,ylab="Base aleta dorsal (mm)", main="Especies de la familia
Carangidae",cex.main=2.0, font.main=2)

#Permite que se añada un nuevo gráfico al ya existente


par(new=T)

#Representa los datos de longitud con la recta de regresión y el intervalo de confianza


matplot(Longitud,Conf, type="l",lty=c(1,2,2),xlim=c(0,700),
ylim=c(0,400),col=c(1,2,2),xlab="",ylab="")
82

2.3.2. Gráficos con barras de desviaciones


Una representación muy común es la de medias y sus errores o desviaciones estándar y, para ello, se
puede usar la función “plotCI( )”. Para que se pueda trabajar con este gráfico es necesario tener
instalado el paquete “gplots” (Warnes, 2012). En este ejemplo hay datos del área de distribución
geográfica de diferentes especies de tiburones, que están en el archivo Tiburones.csv, los cuales
contienen la media y la desviación típica para cada familia de tiburones.

library(gplots)

datos = read.csv2("Tiburones.csv",header=TRUE,encoding= "latin1")

# esta función amplía la ventana de presentación del gráfico.


windows(12,8)

plotCI(datos$Tipo,datos$Media,uiw=datos$STD,xlim=c(0,7),ylim=c(0,250000000),pch=15,
col="bla ck",ylab="",xlab="Familia",
font.axis=1,font.lab=1,cex.axis=1.3,cex.lab=2.5,main="Area geográfica de
tiburones",font.main=2,cex.main=2.5,cex=1.5,xaxt="n",gap=0)

text(datos$Tipo,datos$Media,labels=datos$Familia,pos=2,offset=0.5,cex=1.6)

mtext(expression(paste("Area media por especie (km"^2,")")),2,line=2.2, font=1, cex=1.8)


83

2.3.3. Diagrama de cajas


El diagrama de cajas se utiliza para variables cuantitativas. Se representa la mediana (línea gruesa
dentro de la caja) y otros parámetros relacionados con su dispersión. La caja abarca el rango en el que
se encuentran el 1er y 3er cuartil. Las líneas punteadas indican el máximo y el mínimo si no hay outliers,
o 1.5 veces la longitud de la caja si los hay. Los outliers se representan como puntos aislados más allá
de los límites de la línea punteada.

Representaremos con un diagrama de cajas la tasa de crecimiento de rotíferos a los que se somete a
diferentes tratamientos, algunos de ellos con alimento tóxico.

datos = read.csv2("Rotíferos.csv",header=TRUE,encoding="latin1")
attach(datos)

boxplot(r~Treatment)
title("Tasa de crecimiento de los rotíferos",xlab="Tratamiento", ylab="r",font.main=2,
font.lab=2,cex.main=1.25)

Actividad en clase: Describa brevemente y analice el gráfico de cajas y bigotes para el conjunto de
datos InsectSprays del paquete {datasets}.
84

2.3.4. Histogramas
El histograma representa las frecuencias de una variable continua mediante áreas. Con la función
“hist( )” representaremos el histograma.
85

Ejemplo # 1. Veremos un ejemplo de histograma sobre el que representaremos una curva de densidad
de probabilidad. Jugando con los argumentos de la función para crear histogramas definiremos las
clases de forma que cada barra represente –en lo posible- la frecuencia absoluta o relativa de solamente
un valor. Los datos que disponemos son una serie de parámetros celulares correspondientes a una
población de microalgas en el archivo Microalgas.csv. Las unidades de medida se corresponden con
una señal eléctrica de un determinado detector en un citómetro de flujo. Nos interesa representar un
histograma sin agrupar los tamaños en clases, de modo que a cada valor individual de la variable le
corresponda su densidad de probabilidad en el eje y.

datos = read.csv2("Microalga.csv",header=TRUE,encoding="latin1")
attach(datos)

hist(Tamaño,breaks=length(Tamaño),xlim=c(0,1000),ylim=c(0,0.02), main="Tamaño del alga",


xlab="Tamaño",ylab="Densidad" ,font.main=2, font.lab=2,cex.main=1.25,freq=FALSE,
xaxp=c(0,1000,10))

lines(density(Tamaño,na.rm=TRUE),lwd=2,col="red")

Ejemplo # 2. También es posible representar dos series de datos en la misma gráfica. En este ejemplo,
además de representar el tamaño se representa la rugosidad; ambas variables se miden en mV
(milivolitios) y tienen un rango similar.

datos = read.csv2("Microalga.csv",header=TRUE,encoding="latin1")
attach(datos)

hist(Tamaño,breaks=length(Tamaño),xlim=c(0,1000),ylim=c(0,0.02),
main="Tamaño y Rugosidad",xlab="mV",ylab="Densidad",font.main=2,
font.lab=2,cex.main=1.25,freq=FALSE,border="grey22")

par(new=TRUE)

hist(Rugosidad,breaks=length(Tamaño),xlim=c(0,1000),ylim=c(0,0.02),
main="",xlab="",ylab="",freq=FALSE,border="grey55")

lines(density(Tamaño,na.rm=TRUE),lwd=2,col="red")
lines(density(Rugosidad,na.rm=TRUE),lwd=2,col="blue")
legend(0,0.0175,c("Tamaño","Rugosidad"),lty=c(1,1),lwd=c(2,2),col=c("red","blue"))
86

2.3.5. Gráficos de barras


El gráfico de barras se utiliza para variables cuantitativas discretas y variables cualitativas. La
función “barplot( )” permite presentar barras simples, barras agrupadas o barras apiladas.

Ejemplo # 1: Para realizar estos tipos de gráficos, usaremos el archivo Morfología.csv, es decir,
medidas morfológicas de una serie de peces clasificados en orden, familia, género y especie. El objetivo
es representar los valores de distintas variables por familia. Aquí solo usaremos la variable M2 para
crear un gráfico de barras simple. Además, dentro de “barplot” calcularemos los valores promedio de
M2 por familias.

datos = read.csv2("Morfología.csv",header=TRUE,encoding= "latin1")


attach(datos)

barplot(tapply(datos$M2,datos$Familia,mean),ylim=c(0,0.16),ylab="Longitud",font.lab=2,
font.axis=2, main="M2",font.main=2)

Ejemplo 2: Ahora representaremos los valores promedio de una serie de variables (M2, M3, M4, M5)
para cada familia, mediante un gráfico de barras agrupadas. Dentro de la función “barplot”, debemos
indicar que el argumento “beside” tenga valor TRUE. De lo contrario, generaría un diagrama de barras
apilados, como veremos en el ejemplo siguiente.

datos = read.csv2("Morfología.csv",header=TRUE,encoding= "latin1")

datos2 = datos[,c("Familia","M2","M3","M4","M5")]

datos2M = aggregate(datos2[,c("M2","M3","M4","M5")],by=list(datos2$Familia),mean)

datos2M = datos2M[,-1]

rownames (datos2M) = c("Characidae","Cichlidae","Sparidae","Sphyraenidae")

datos2M = as.matrix(datos2M)

barplot(t(datos2M),beside=TRUE,ylim=c(0,0.15),main="Morfología",ylab="Longitud",font.main=2,
font.axis=2,font.lab=2,col=1:4)

legend("topleft",colnames(datos2M),bty="n", fill=c("black","red","green","blue"))
87

Ejemplo # 3. Por último, simplemente dejando el valor por defecto del argumento “beside” en el
gráfico del ejemplo anterior, obtendremos un gráfico de barras apiladas.

datos = read.csv2("Morfología.csv",header=TRUE,encoding= "latin1")

attach(datos)

datos2 = datos[ ,c("Familia","M2","M3","M4","M5")]

datos2M = aggregate(datos2[ ,c("M2","M3","M4","M5")],by=list(datos2$Familia),mean)


datos2M = datos2M[ ,-1]
rownames(datos2M) = c("Characidae", "Cichlidae","Sparidae","Sphyraenidae")

datos2M = as.matrix(datos2M)

barplot(t(datos2M),ylim=c(0,0.4), main="Morfología",ylab="Longitud",font.main=2,
font.axis=2,font.lab=2,col=1:4)

legend("topleft", colnames(datos2M),bty="n", fill=c("black","red","green","blue"))

Ejemplo # 4. Versión mejorada del ejemplo 1. Esto se debe a la función “barp()” del paquete
“plotrix” (Lemon, 2012).

install.packages(“plotrix”,dependencies=T)

library(plotrix)

datos = read.csv2("Morfología.csv",header=TRUE,encoding= "latin1")


attach(datos)

#Se calculan las medias por familias para algunas medidas


datos1 = aggregate(datos[ ,c("M2","M3","M4","M5")],by=list(Familia),mean)
datos2 = datos1[ ,-1]
datos3 = t(datos2)
colnames(datos3) = c("Characidae","Cichlidae","Sparidae","Sphyraenidae")
datos3

#Se representan los datos


library(plotrix)
barp(datos3,names.arg=colnames(datos3), cex.axis=1.2, col=rainbow(4),
cylindrical=TRUE,shadow=F,staxx=F,staxy=TRUE, legend.lab=c("M2","M3","M4","M5"),
legend.pos=list(x=0.7,y=0.12), xlab="",ylab="",border=TRUE)
mtext("Familias",1,line=2.8, font=2, cex=1.6)
mtext("Longitud",2,line=2.6, font=2, cex=1.6)
88

2.3.6. Gráficos circulares


Los gráficos circulares o de torta los cuales representan las frecuencias de una variable mediante la
amplitud de un sector circular. Aunque se suele utilizar con variables cualitativas, también es útil para
representar variables cuantitativas. Se utilizará el archivo Población.csv, que contiene datos de la
estructura de la población de hombres y mujeres de España en diferentes años. La función que utilizará
acá es “pie( )”.

Datos = read.csv2("Población.csv", header=TRUE, encoding="latin1")

attach(Datos)

pie(M.1991,labels=Edad,main=paste("Estructura de edad de",sep="\n", "mujeres españolas en


1991"),cex.main=1.55,clockwise=FALSE,init.angle=0,radius=1)

Actividad en clase: Realice un diagrama circular sobre un grupo aleatorio de 50 personas entre
hombres, mujeres y niños. Añada los porcentajes que representa cada uno.
89

2.3.7. Uso del paquete ggplot2


Como hemos visto a través de los ejemplos anteriores los gráficos que contiene R dentro de su biblioteca
base graphics package son extremadamente poderosos y flexibles para generar gráficos de alta calidad,
sin embargo, requieren de varios o muchos argumentos para lograrlo.

Hadley Wickham estadístico neozelandes, es el creador del generador de gráficos más elegante y
visualmente más estético del Software R, al que llamó ggplot2. Actualmente, se encuentra dentro de los
5 paquetes con mayor descarga dentro del CRAN.

Al iniciar, la sintaxis que maneja el paquete puede ser un poco complicada, pero a medida que se utilice
con mayor frecuencia, los esfuerzos valdrán la pena, ya que los resultados a nivel estético resaltan a la
vista con menos líneas de comando. Por ejemplo, si yo quisera construir un gráfico de dispersión a través
de la función plot {graphics} que sea muy similar al que gerenera ggplot {ggplot}, requerirá de al menos
30 lineas más de comando.

Para ver las diferencias que existen entre los dos, se usará el conjunto de datos iris {datasets} que se
trabajó en la primera parte de la sección 2.3 (ir a pág.78).

2.3.7.1 ggplot2: Diagramas de Dispersión.


Recordando el problema del conjunto de datos iris, se realizará dos gráficos de dispersión: el primero
se construirá a través de la función plot() tal como se hizo al principio de esta sección y el segundo a
través de la función ggplot() de {ggplot2}.

data("iris")
attach(iris)

# Usando la función plot {graphics}

plot(iris[Species=="setosa","Petal.Length"],iris[Species=="setosa","Sepal.Length"],xlim=c(0,9),
ylim =c(3,9),pch=19,col="blue",xlab="",ylab="",bty="l")

points(iris[Species=="virginica","Petal.Length"],iris[Species=="virginica","Sepal.Length"],
pch=19,col="green")

points(iris[Species=="versicolor","Petal.Length"],iris[Species=="versicolor","Sepal.Length"],
pch=21, bg="red")

title(main="Longitud de Pétalo vs Longitud de sépalo",xlab="Longitud de pétalo (cm)",


ylab="Longitud de sépalo (cm)",font.main=2,font.lab=2,cex.main=1.5)

legend("topleft",c("setosa","virginica","versicolor"),bty="n",
pch=c(19,19,19),col=c("blue","green","red"))
90

# Usando la función qplot {ggplot2}


http://www.statmethods.net/advgraphs/ggplot2.html

# Recuede instalar previamente el paquete "ggplot2"


# Manualmente sería: > install.packages(pkgs="ggplot2",dependencies = T)

library(ggplot2)
qplot(Petal.Length, Sepal.Length, data = iris, color = Species, size = Petal.Width, alpha = I(0.7),
main = "Longitud de Pétalo vs Longitud de sépalo",xlab ="Longitud de pétalo (cm)",ylab="Longitud
de sépalo (cm)" )
91

2.3.7.2 ggplot2: Diagramas de Caja y Bigotes.


data("iris")
attach(iris)
library(ggplot2)

# Usando la función plot {graphics}

boxplot(Petal.Width~Species,xlab="Especie", ylab="Ancho del Pétalo",font.main=2,


col=c("lightblue","lightgreen","lightyellow"),
main="Distribución del Ancho del Pétalo de \n cada Especie de Flor")
92

# Usando la función qplot {ggplot2}

qplot(Species, Petal.Width, data=iris, geom=c("boxplot"),


fill=Species, main="Distribución del Ancho del Pétalo de cada Especie de Flor",
xlab="Especie", ylab="Ancho del Pétalo")

# Usando la función ggplot {ggplot2}


http://docs.ggplot2.org/current/geom_boxplot.html

p=ggplot(iris,aes(x = Species,y = Petal.Width))


p+geom_boxplot(aes(colour=Species),outlier.colour = "red")+geom_jitter(width = 0.2)
93

2.3.8. Gráficos de contorno y superficies


Los gráficos de contornos son fáciles de realizar en R si disponemos de los datos adecuados. Hay varias
funciones en el paquete “graphics” como <<image()>>, <<contour ( )>> y <<filled.contour ( )>>
que nos permiten realizar este tipo de gráficos. La función <<contour ( )>> permite hacer mapas
topográficos.

Ejemplo # 1. En el archivo Batimetría.csv hay datos de profundidades y de alturas de islas en una


zona del océano donde hay fosas abisales, que fueron obtenidas de la página web
http://rda.ucar.edu/datasets/ds759.2/. Se empleará la función de interpolación “interp( )”, presente
en el paquete “akima”, por lo que es necesario instalarlo. El argumento <<type=”n”>> indica que no se
presente ningún marcador en el eje. El argumento <<pty=”m”>> indica que la región del gráfico sea la
máxima posible cuando se amplía la pantalla. El argumento <<fg=”blu”>> modifica el color del marco,
líneas y texto del gráfico.

library(akima)
Datos = read.csv2("Batimetría.csv", header=TRUE, encoding="latin1")
attach(Datos)
input = interp(Datos$Longitud, Datos$Latitud, Datos$Profundidad)
par(pty = "m",fg="blue")
plot(x = 0, y = 0,type = "n", xlim = c(130,150), ylim = c(33,35), xlab = "Longitud",
ylab = "Latitud",cex.lab=1.7,font.lab=2, cex.axis=1.6)
contour(input, lty = "solid", add = TRUE, vfont = c("sans serif", "plain"), labcex=1.2)
title("atimetría y Altimetría entre 33º N a 35ºN y 130ºE a 150ºE", font = 2, cex.main=2)

Si se realiza un pequeño cambio y se especifica <<pty=”s”>>, la región del gráfico es cuadrado, como se
verá al correr la rutina siguiente, y no se hace rectangular cuando se amplía la ventana, tal como se
observó en el anterior. Si además se pone <<fg=”black”>>, se observa como ahora el gráfico es en negro
en lugar de azul.

Datos = read.csv2("Batimetría.csv", header=TRUE, encoding="latin1")


attach(Datos)
input = interp(Datos$Longitud, Datos$Latitud, Datos$Profundidad)
par(pty = "s",fg="black")
plot(x = 0, y = 0,type = "n", xlim = c(130,150), ylim = c(33,35), xlab = "Longitud",
ylab = "Latitud",cex.lab=1.7,font.lab=2, cex.axis=1.6)
contour(input,lty = "solid", add = TRUE,vfont = c("sans serif", "plain"),labcex=1.2)
title("Batimetría y Altimetría entre 33º N a 35ºN y 130ºE a 150ºE", font = 2, cex.main=2)

Ejemplo # 2. Ahora en este ejemplo se empleará la función <<filled.contours( )>>. En el archivo


Riqueza.csv hay datos de número de especies para diferentes latitudes y longitudes. Para este tipo de
funciones, primero tenemos que crear un objeto dividido en niveles con un intervalo regular, ycon
94

valores crecientes de las variables x e y. si no disponemos de esos datos, como es nuestro caso, debemos
generarlos. Para ello nos sirve la función <<interp( )>>, del paquete “akima”. Una vez que se posea este
objeto, es muy fácil hacer uso de la función gráfica <<filled.contour()>>.

library(akima)
datos = read.csv2("Riqueza.csv",header=TRUE,encoding="latin1")
attach(datos)
#función interp() no admite NA.
Input = interp(Longitud.Oeste,Latitud.Sur,Riqueza.especies, duplicate= "mean")
filled.contour(input,xlab="Longitud",ylab="Latitud",main="Riqueza de especies",font.lab=2,
plot.axes = {
axis(1, seq(50, 70, by = 5))
axis(2, seq(0, 20, by = 2))}, # se han especificado los intervalos de los ejes
key.title =title(main="Número\n especies", cex.main=1.1), # indica el título del gráfico
key.axes = axis(4, seq(0, 35, by = 5)))
95

2.3.8. Gráficos tridimensionales


Otra función gráfica interesante es <<persp>>, la cual permite realizar gráficos en tres dimensiones.
Los datos que se utilizan, que están en el archivo Altimetría.csv, son de altimetría y batimetría, desde
el Golfo de Omán hasta la estepa Siberiana, en específico para una latitud desde 23°10 ´ N hasta 61°5 ´
N y una longitud desde 61°E hasta 117°30 ´ E.

Datos = read.csv2("Altimetría1.csv", header=TRUE, encoding="latin1")

windows(w=15.5,h=9.5) # especifica la creación de una nueva ventana con un tamaño específico de alto y
#ancho, con el fin de ver el gráfico más grande.
z = as.matrix(Datos) # convierte los datos en una matriz
x = 100 * (1:nrow(z)) # se multiplica por 100 para que el espacio sea mayor entre coordenadas, quedando
#más claro el gráfico.
y = 100 * (1:ncol(z))
persp(x, y, z, theta = 120, phi = 20, scale = FALSE, box=TRUE, zlab="Metros", xlab="Latitud",
ylab="Longitud", cex.lab=2)
title("Latitud 23º25´N a 61º5´N y Longitud 61ºE a 117º30´E", font = 2, cex.main=2)

Pequeñas modificaciones pueden dar lugar a cambios importantes en el formato. Con la instrucción
<<phi>> se puede cambiar el ángulo de visión. La instrucción <<theta>> permite cambiar la orientación
del gráfico; el argumento <<border=NA>> elimina el borde, dándole un aspecto más uniforme. La
instrucción <<shade>> permite dar sombras. Por último, la instrucción
<<ticktype=”datailed”>> pone intervalos en los ejes del gráfico con sus correspondientes valores.

windows(w=15.5,h=9.5)

persp(x, y, z, theta = 20, phi = 20, scale = FALSE, zlab="Metros", xlab="Latitud",


ylab="Longitud", cex.lab=2, box=TRUE, border=NA, shade=0.5, ticktype="detailed")

title("Latitud 23º15´N a 61º5´N y Longitud 61ºE a 117º30´E", font = 2, cex.main=2)


96

2.3.9. Configuración de márgenes y ejes adicionales


Para el ejemplo que trabajaremos se usaran series temporales para mostrar cómo se pueden incluir
varios ejes “y” en el gráfico para representar variables cuyas escalas son muy diferentes. Se trata de
una serie temporal de medidas mensuales, de dos años de duración, realizadas en una laguna. Las
variables medidas son: eclosión promedio de larvas de mosquito por metro cuadrado, materia orgánica
particular en mgl-1 y temperatura media del agua en el momento del muestreo. Representaremos un
eje y distinto para cada variable. Los datos están en el archivo Mosquitos.csv.

datos = read.csv2("Mosquitos.csv",header=TRUE,encoding="latin1")

attach(datos)

par(oma=c(1,1,1,9), bg="grey98") # <<par>>: establece un tamaño para los márgenes externos. Y <<bg>>
#permite colocar el color del fondo del área donde se pondrán los gráficos.

par(mex=0.6) # al ser menor que 1, permite que la figura se pueda pegar más a los bordes del marco.

plot(Mes,Mosquitos,type="b",lty=1,lwd=2,ylim=c(0,65),font.lab=2, yaxs="i")

par(new=TRUE) # permite pegar un Nuevo gráfico sobre el anterior.

plot.default(Mes,Temp,ylim=c(0,30),ann=FALSE,yaxt="n",type="l",lty=1, yaxs="i")

# En los nuevos gráficos, indicamos que el eje “y” no se represente <<yaxt0”n”>>.


# Ese eje los dibujaremos después con la función <<axis( )>>, indicando el margen (4 significa a la derecha).

axis(4)
mtext("Temperatura",4,line=3,font=2)

par(new=TRUE)
plot.default(Mes,POM,ylim=c(0,6),ann=FALSE,yaxt="n",type="l",lty=3,lwd = 2, yaxs="i")

axis(4,line=4,outer=TRUE)
mtext("POM",4,line=9,font=2)

title("Eclosión de larvas de mosquito", cex=2, font=2,adj=0.5)


legend("topleft",c("Mosquitos","Temperatura","POM"),bty="n",pch=c(21,NA,NA),lty=c(1,1,3),
lwd=c(2,1,2))
# representa una línea vertical roja que divide el estudio en #dos periodos.
rug(12,5,ticksize=1,side=3, lwd=3, col="red")
box(which="outer") # pinta un marco exterior.

rug(12,5,ticksize=1,side=3, lwd=3, col="red")

par("cra","din") # informa sobre el tamaño del


# área donde se muestran los gráficos en píxeles y en pulgadas.
97

2.3.10. Gráficos dentro de gráficos


Con las instrucciones <<par(new=T, omd= c(x1,x2,y1,y2))>> es posibles insertar fácilmente gráficos
dentro de otros gráficos. Los valores x1, x2, y1 e y2 solo pueden ser entre 0 y 1, e indican la posición
relativa de la figura dentro del panel. El argumento <<par(omi=c(x1,x2,y1,y2))>> indica lo mismo pero
en pulgadas. Ahora, usando nuevamente el archivo Cangidae.csv, represente la relación entre dos
variables y luego se inserta un histograma de cada una para averiguar si la distribución es Normal.

Datos = read.csv2("Carangidae.csv", header=TRUE, encoding="latin1")


attach(Datos)

#Se representan los datos

plot(Longitud,Dorsal,xlim=c(0,700), ylim=c(0,400), xlab="Longitud estándar (mm)", cex.lab=1.6,


font.lab=2,ylab="Base aleta dorsal (mm)", main="Especies de la familia
Carangidae",cex.main=2.0, font.main=2)

#Primer histograma

par(new=T, omd=c(0,0.6,0.55,1))

hist(Dorsal,breaks=length(Longitud),main="",xlim=c(0,400), xlab="", ylab="",cex.lab=1,font.lab


=1,freq=FALSE, yaxt="n")

lines(density(Dorsal,na.rm=TRUE),lwd=2,col="red")

mtext("Base aleta dorsal (cm)",1,line=2,font=2)

#Segundo histograma

par(new=T, omd=c(0.39,0.99,0.1,0.55))

hist(Longitud,breaks=length(Longitud),main="",xlim=c(0,800),

xlab="", ylab="",cex.lab=1,font.lab =1,freq=FALSE, yaxt="n")

lines(density(Longitud,na.rm=TRUE),lwd=2,col="red")

mtext("Longitud estándar (cm)",1,line=2,font=2)


98

2.3.11. Ampliación de un área dentro de un gráfico


La función <<zoomInPlot( )>> del paquete “plotrix” (Lemon, 2012) permite ampliar un rango de
valores dentro de un gráfico. Como ejemplo usaremos los datos, que están en el archivo Clima.csv, de
temperatura del agua y del aire, y la intensidad del viento de Este a Oeste (Viento.X) y de Sur a Norte
(Viento.Y) a 42° norte y 10° Oeste, desde 1925 hasta 1997.

library(plotrix)

datos = read.csv2("Clima.csv",header=TRUE,encoding="latin1")

attach(datos)

zoomInPlot(Temperatura.agua,Temperatura.aire,xlim=c(10,20),ylim=c(10,20),

rxlim=c(12,14),rylim=c(12,14), xend=NA, xlab="Temperatura del agua (ºC)",

ylab="Temperatura del aire (ºC)",zoomtitle="Ampliación en el rango de 12 a 14 ºC",titlepos=11.3,


pch=2, col="blue")
99

2.3.12. Paquetes que permiten realizar varios tipos de


gráficos básicos

Hay algunos paquetes en R que tienen un formato de ventanas, con diferentes menús, que permiten
realizar algunos de los gráficos mostrados anteriormente. Hasta el momento hay dos: R Commander
y GrapheR. El primero es el más popular.

2.3.12.1 R COMMANDER
R Commander es una Interfaz Gráfica de Usuario (GUI) que facilita considerablemente el uso de R.
Contiene un menú que permite – de forma similar a otros programas estadísticos- realizar de modo
sencillo la mayoría de las operaciones estadísticas habituales, y separa las instrucciones y resultados
en dos ventanas diferentes.

Para utilizar R Commander hay que instalar el paquete “Rcmdr” (Fox 2005, 2007; Fox y col., 2012).
En general, al mismo tiempo se instalan automáticamente todos los paquetes dependientes o
complementarios necesarios para un funcionamiento correcto. Normalmente, cuando se arranca por
primera vez instala más paquetes, que son necesarios para que funcione.
Los diseñadores de R Commander trataron de incluir en él todas las técnicas contenidas en un curso
básico de Estadística, añadiendo posteriormente algunas otras técnicas de su común, pero después han
preferido mantener su estructura simple en lugar de seguir añadiendo técnicas en un menú
crecientemente complejo que intente cubrir todos los métodos.

La principal ventaja de R Commander es que el usuario puede realizar casi todas las operaciones
estadísticas de tratamiento de datos sin conocer en absoluto el complejo lenguaje de programación. R
Commander se encarga de construir las órdenes a partir del menú, como lo hacen otros programas
estadísticos (SPSS, StatGraphics, InfoStat, etc.). Sin embargo, el conocimiento del lenguaje de
programación de R permite multiplicar la potencia estadística y mejorar los resultados y su
presentación, para lo cual se pueden modificar convenientemente las órdenes generadas inicialmente
por R Commander.

Para iniciar R Commander teclamos (recuerde que en R siempre es necesario respetar las mayúsculas)
la instrucción siguiente en la consola de R (RGuis):
100

library(Rcmdr)

De otro modo sería:


101

Y finalmente:
102

A continuación se muestra la Interfaz de R Commander:


103

La separación de instrucciones y resultados en ventanas diferentes es muy conveniente para una mejor
organización de todos los elementos de la aplicación estadística. Además R Commander muestra una
tercera ventana de <<Mensajes>>, en la que advierte de cualquier error o problema en la aplicación.

Para probar un poco este nuevo ambiente, introduzcamos en la <<Ventana de instrucciones>> lo


siguiente:

X=c(34,47,56,3,78,36,56,23,14)
Y=c(36,41,55,4,75,38,58,21,16)
#Gráfico que relaciona ambas variables
plot(X,Y)

Ahora a modo de ejemplo, vamos a utilizar datos reales de nuestra base de datos, que se encuentran
en el archivo PigAlgas.xls. (datos de pigmentos de algas). Lo mejor para R Commander es usar archivos
de Excel 2003 (extensión “xls”). En el menú se selecciona <<Datos>>, luego <<Importar datos>>, luego
<<desde conjunto de datos Excel, Access o dBase>>. Aquí podremos explorar un poco los diferentes
análisis estadísticos que en particular quisiera abordar (como por ejemplo la elaboración de un
diagrama de cajas resaltando la variable categórica Especie), con el fin de conocer las diferentes
opciones que R Commander ofrece.

Nota: Como práctica en clase se podría verificar nuevamente algunos resultados que se obtuvieron de
gráficos anteriores o análisis estadísticos que ya hemosrealizado.
104

2.3.13. Representaciones interactivas para páginas web.


La aplicación de Interface de Programación (API) de visualización de Google permite realizar
representaciones dinámicas, las cuales se pueden incorporar a páginas web. El paquete “googleVis”
(Gesmann y de Castillo, 2011; 2012) proporciona una interfaz entre R y la API de visualización de
Google. Es necesario tener conexión a internet.

2.3.13.1 GRÁFICOS
En el archivo Banco mundial.csv hay datos obtenidos de la página web
http://datos.bancomundial.org/, donde se puede observar el porcentaje de población y de
desempleados para diferentes edades, así como la población total y el número de mujeres, en
diferentes regiones del mundo.

La función <<gvisMotion( )>> del paquete “googleVIs” prepara objetos que luego pueden ser
representados en forma de gráficos dinámicos en páginas web. Con el argumento <<idvar>> se
especifica la variable de identificación, en este caso las diferentes regiones. Con <<timevar>> se define
la variable que contiene la información de tiempo. Existe otro argumento
<<date.format=”%Y/%m/%d”>>, que permite definir el formato de tiempo, en el caso de que no fueran
años.

library(googleVis)

datos=read.csv2("Banco mundial.csv",header=TRUE,encoding="latin1")

G = gvisMotionChart(datos, idvar = "Region", timevar = "Year")

plot(G)

La función <<gvisAnnotated>> del paquete “googleVis”, permite representar series temporales. En el


archive Mareas.csv hay datos del ángulo entre el sol y la luna, y la diferencia en metros entre pleamar
y bajamar, para 42° 8 ´ Norte y la 14° 13 ´Oeste, del 1/1/2004 al 14/3/2004.
105

En el argumento <<datevar>> se introduce la variable que tiene los datos de las fechas. En
<<nunvar>> la variable a representar. En <<idvar>> se podría poner una variable identificativa, de
tal froma que habría tantas series temporales como grupos tuviese esa variable. El argumento
<<titlevar>> permite poner una variable con eventos, que en este ejemplo son las diferentes fases de
la luna. Con el argumento <<options>> es posible introducir modificaciones en el gráfico, las cuales se
pueden consultar en el menú de ayuda de la función.

library(googleVis)

datos = read.csv2("Mareas.csv",header=TRUE,encoding= "latin1",fill=TRUE)

G2 = gvisAnnotatedTimeLine(datos, datevar="Fecha",numvar="Angulo.Sol.Luna",
idvar="",titlevar="Fase", options=list(displayAnnotations=TRUE,legendPosition='newRow',
width=1000, height=500))

plot(G2)

2.3.13.2 TABLAS
Las tablas se realizan con la función <<gvisTable( )>> del paquete “googleVis”. El siguiente Script
muestra como generar tablas interactivas para páginas de internet usando de nuevo el archivo de
Banco mundial.csv. En la función <<gvisTable( )>>, con el argumento <<options>> es posible
introducir modificaciones en la tabla, las cuales se pueden consultar en el menú de ayuda de la función.

library(googleVis)

datos = read.csv2("Banco mundial.csv",header=TRUE,encoding="latin1")

T = gvisTable(datos,options = list(width = 1000, height = 500, page= "enable"))

plot(T)
106

2.3.13.3 COMBINACIÓN DE REPRESENTACIONES


La función <<gvisMerge( ) >> del paquete “googleVis” permite combinar gráficos, tablas y/o mapas en
una sola pantalla. En este apartado realizaremos la integración de gráficos y tablas utilizando los datos
del archivo Banco mundial.csv del ejemplo anterior. Después de generar el gráfico y la tabla, como se
explicó anteriormente, ambos se integran en un mismo dispositivo con <<gvisMerge( )>>. El
argumento <<horizontal=FALSE>> significa que se pongan en la misma columna, en diferentesfilas.

library(googleVis)

datos = read.csv2("Banco mundial.csv",header=TRUE,encoding="latin1")

#Gráfico

G = gvisMotionChart(datos, idvar = "Region", timevar = "Year")


#Tabla

T = gvisTable(datos,options = list(width = 500, height = 250, page= "enable"))


#Integración de ambos

GT = gvisMerge(G, T, horizontal = FALSE)

plot(GT)
107

2.4. GRÁFICOS AVANZADOS

En esta parte de los gráficos avanzados debido a la gran diversidad que existe, mencionaré algunos de
ellos. Donde solo se indicará el nombre del gráfico, el nombre del archivo donde se encuentran los
datos para correr el script, el nombre de la función principal para ejecutar dicho gráfico y la rutina del
script.

2.4.1. Gráficos demográficos

1. Tema: Estructura de edad de una población.


2. Archivo: Población.csv.
3. Función principal: <<pyramid.plot( )>>. Paquete “plotrix”
4. Instrucciones del script:

library(plotrix)

Datos=read.csv2("Población.csv", header=TRUE, encoding="latin1")


attach(Datos)

#Los datos se transforman a porcentajes


s<-sum(H.1991) + sum(M.1991)+ sum(HE.1991)+ sum(ME.1991)
M1991<-M.1991*100/s; H1991<-H.1991*100/s ME1991<-
ME.1991*100/s; HE1991<-HE.1991*100/s

#Primer gráfico
pyramid.plot(H1991,M1991,labels=Edad,
main="Población española y extranjera en España en 1991",lxcol="blue",rxcol="pink",labelcex=1.2,
unit="%",
gap=1,show.values=T, top.labels=c("Hombres","Edad","Mujeres"),ndig=1,xlim=c(5,5))

#Segundo gráfico
pyramid.plot(HE1991,ME1991,lxcol="red",rxcol="red",
labelcex=0, gap=1,show.values=F, ndig=2,xlim=c(5,5),add=T)

legend(3.5,19, c("Hombres", "Mujeres", "Extranjeros"), bty="n",


pch = c(15,15,15), col=c("blue","pink","red"))
108

2.4.2. Gráficos de burbujas

1. Tema: Estructura de edad de una población.


2. Archivo: AARotíferos.csv.
3. Función principal: <<size_n_color( )>>. Paquete “plotrix”
4. Instrucciones del script:

library(plotrix)

Datos =read.csv2("AARotíferos.csv", header=TRUE, encoding="latin1")


attach(Datos)

Ab = Datos$Abundancia/10
size_n_color(Temperatura, Conductividad, Ab, cex.main= 1.6, color.scale (AA,c(0.8,0),c(0.8,1),1),
pch=16, xlab="", ylab="", main="Abundancia y concentración de aminoácidos", xat=seq(20,35,by=5),
yat=seq(0,2,by=0.5), xlim = c(20,35), ylim=c(0,2)) points(21,1.9,cex=10);text(22,1.9,"100 Individuos
por litro",cex=1.2, pos=4) points(21,1.685,cex=2.5);text(22.8,1.685," 25",cex=1.2)

points(21,1.580,cex=1);text(22.8,1.58," 10",cex=1.2)
color.legend(20,0,21,0.50,seq(4500,6500,by=500),gradient="y",align="rb",
rect.col=color.scale(seq(4500,6500,by=500),c(0.8,0),c(0.8,1),1))
text(23.8,0.28,"Picomoles", cex=1.2) text(23.8,0.195,substitute("individuo"^-
1),cex=1.2) mtext(expression(paste("Conductividad (mScm"^-2,")")), 2, line=2.4, font =
1, cex=1.4) mtext(expression(paste("Temperatura (ºC)")), 1, line=2.8, font = 1, cex=1.4)

2.4.3 Gráficos de escalera

1. Tema: Pérdida de biomasa desde los productores primarios hasta los secundarios, debido a las
pérdidas en el consumo, asimilación y respiración.
2. Archivo: Dentro de la instrucción
3. Función principal: <<staircase.plot( )>>. Paquete “plotrix”
4. Instrucciones del script:

library(plotrix)

datos = c(100,-20,-25,-30,25)
totals = c(TRUE,FALSE,FALSE,FALSE,TRUE)
labels = c("Producción primaria","Eficiencia de consumo","Eficiencia de asimilación", "Eficiencia de
producción","Producción secundaria") staircase.plot(datos,totals,labels,halfwidth=0.3,
main="Transferencia biomasa de productores primarios a secundarios",
total.col="gray",inc.col=2:4,bg.col="#eeeebb",direction="s", display.height=T, stagger=F)
109

2.4.4 Gráficos de telaraña

1 Tema: Metales en sedimentos a distintas profundidades.


2 Archivo: Metales.csv.
3 Función principal: <<radial.plot( )>>. Paquete “plotrix”
4 Instrucciones del script:

library(plotrix)

Datos = read.csv2("Metales.csv", header=TRUE, encoding="latin1")


attach(Datos)

radial.plot(Datos[,2],labels=Metal,rp.type="p",main="Metales en sedimentos (ppm)",


line.col="red",show.grid=T,lwd=2, lty=1, radial.lim=c(0,70), radlab=F,
label.prop=1.1,show.grid.labels=2,
grid.col="grey",grid.bg="transparent")

radial.plot(Datos[,3],labels=Metal,rp.type="p",line.col="blue",show.grid=T,lwd=2,
radial.lim=c(0,70),
label.prop=1.1,show.grid.labels=2,add=T)

radial.plot(Datos[,4],labels=Metal,rp.type="p",line.col="green",show.grid=T,lwd=2,
radial.lim=c(0,70),
label.prop=1.1,show.grid.labels=2, add=T)

radial.plot(Datos[,5],labels=Metal,rp.type="p",line.col="orange",show.grid=T,lwd=2,
radial.lim=c(0,70),
label.prop=1.1,show.grid.labels=2,add=T)

legend("topleft", c("1 cm", "50 cm", "100 cm", "200 cm"), bty="y",
pch = c(15,15,15,15), col=c("red", "blue","green","orange"))
110

2.4.5 Matrices de gráficos

1 Tema: Se usará los datos de clorofila, afloramiento, temperatura y nutrientes de diferentes


zonas costeras del mundo.
2 Archivo: Producción primaria.csv.
3 Función principal: <<pairs( )>>. Paquete “lattice”
4 Instrucciones del script:

Modelo # 1:

library(lattice)

datos = read.csv2("Producción primaria.csv",header=TRUE,encoding="latin1")


attach(datos)

#Gráfico 1
datos1 = datos[,c("Clorofila","Fosfato","Nitrato","Silicato")]
pairs(datos1,main="Clorofila y nutrientes",cex.main=2, cex=1.5, pch=15,cex.labels=2.8)

Modelo # 2:

library(vcd)

pairs(datos1, pch=21, bg=c("red","blue","cyan","yellow")[unclass(datos$Area)],cex=1.8)

grid_legend(0.2, 0.99, pch=c(19), col=c("red"),c("Benguela"),title="",frame=FALSE)


grid_legend(0.4, 0.99, pch=c(19), col=c("blue"),c("California"),title="",frame=FALSE)
grid_legend(0.6, 0.99, pch=c(19), col=c("cyan"),c("Humbolt"),title="",frame=FALSE)
grid_legend(0.8, 0.99, pch=c(19), col=c("yellow"),c("Mauritania"),title="",frame=FALSE)
111

Modelo # 3:

Nota: Para correr este gráfico es necesario tener instalados los paquetes “MASS”, “ellipse” y
SciViews”

library(SciViews)

panel.hist = function(x, ...)


{
usr <- par("usr"); on.exit(par(usr))
par(usr = c(usr[1:2], 0, 1.5));h <- hist(x, plot = FALSE)
breaks <- h$breaks; nB <- length(breaks)
y <- h$counts; y <- y/max(y)
rect(breaks[-nB], 0, breaks[-1], y, col="cyan", ...)
}
pairs(datos1, main="Clorofila y nutrientes",cex.main=2, lower.panel=panel.smooth,
upper.panel=panel.reg,
cex = 1.2, pch = 24, bg="light blue",diag.panel=panel.hist, cex.labels = 2, font.labels=2)
112

2.4.6 Gráficos para grandes conjuntos de datos


Uno de los problemas que se plantea al realizar una gráfica cuando hay muchos datos es que no es
posible tener una idea de cuantos datos hay en las zonas en las que hay solapamiento. El paquete
“IDP.misc” (Locher y col., 2012) tiene varias funciones para realizar diferentes tipos de gráficos
específicos para series con muchos datos.

2.4.6.1 Dispersión

1 Tema: Valores mensuales de temperatura del agua y el aire, y la intensidad del viento de este a
oeste (Viento.X) y de sur a norte (Viento.Y) a 42° norte y 10° oeste, desde 1925 a 1997.
2 Archivo: Clima.csv.
3 Función principal: <<iplot( )>>. Paquete “IDP.misc”
4 Instrucciones del script:

Modelo # 1:

library(IDPmisc)
datos = read.csv2("Clima.csv", header=TRUE, encoding="latin1")
attach(datos)

zmax = iplot(Temperatura.agua,Temperatura.aire, pixs=3, d.main=1, xlab="Temperatura del agua


(ºC)", ylab="Temperatura del aire (ºC)", cex.lab=1.5,main="42º Norte 10º Oeste", cex.main=1.7)

Modelo #2:

iplot(Temperatura.agua,Temperatura.aire,zmax=zmax, pixs=3, d.main=1, xlab="Temperatura del


agua (ºC)", ylab="Temperatura del aire (ºC)", cex.lab=1.5,main="42º Norte 10º Oeste", cex.main=1.7,
border=T)
113

2.4.6.2 Matrices de gráficos

1 Tema: Valores mensuales de temperatura del agua y el aire, y la intensidad del viento de este a
oeste (Viento.X) y de sur a norte (Viento.Y) a 42° norte y 10° oeste, desde 1925 a 1997.
2 Archivo: Clima.csv.
3 Función principal: <<ipairs( )>>. Paquete “IDP.misc”
4 Instrucciones del script:

library(IDPmisc)
datos = read.csv2("Clima.csv", header=TRUE, encoding="latin1")
attach(datos)

datos1 = datos[ ,3:6]

#Gráfico con la barra de colores sin escala de número de datos


zmax = ipairs(datos1, pixs=2, main="42º Norte 10º Oeste", d.main=1)

#Gráfico con la barra de colores con la escala de número de datos


ipairs(datos1, pixs=2, zmax=zmax, main="42º Norte 10º Oeste",d.main=1, border=T)
114

_______________________________________________________________________________________

UNIDAD 3

SIMULACIONES EN R

3. 1. Generación de números aleatorios


3.1.1. Funciones para distribuciones de probabilidad en R
 rnorm: genera números aleatorios normalizados con una media y desviación
estándar dada.

 dnorm: evalúa la densidad de la probabilidad normal (con una media y desviación


estándar dada) a un punto (o vector de puntos).

 pnorm: evalúa la función de la distribución acumulada para una distribución


normal.

 rpois: genera números aleatorios de Poisson con un valor promedio de éxito dado.

Lo anterior solo fue un ejemplo para distribución Normal, pero también es posible generar
números aleatorios para el resto de distribuciones conocidas (Seguir link)

Además, se podrá notar que las funciones de distribución de probabilidad usualmente


tienen cuatro funciones asociadas con ellas. Las funciones son prefijadas con una:

 d: para la función de densidad


 r: para generar números aleatorios
 p: para la función de distribución acumulada
 q: para la función de cuartiles
115

Ejemplos de generación de números aleatorios:

1. Generando números aleatorios para la distribución normal estándar.


x=rnorm(20) ; x

2. Generando números aleatorios para cualquier media y desviación estándar de la


distribución normal.

x=rnorm(20, 30, 3) ; x

summary(x)

3. Generando datos aleatorios para cualquier media de la distribución Poisson.

x=rpois(20, 5 ) ; x

4. Calculando la probabilidad de la distribución acumulada de una distribuciónPoisson.

a) Pr(x <= 8)

ppois(8, 5 )

b) Pr(x <= 13)

ppois(13, 5 )
116

3.1.2. Una función muy importante en simulación.


Sabemos que siempre que nosotros queramos generar números aleatorios, como su mismo
nombre lo indica, me genera nuevos números cada vez que se lo pida aún bajo los mismos
argumentos que éste posea.

Una función muy importante que se debe escribir al principio de cada programa o
simulación que se esté desarrollando es la función set.seed, denominado como “conjunto
semilla”, la cual fija ese conjunto de datos iniciales sin alterarlos. Veamos el siguiente
ejemplo:

set.seed (001) # el valor que se encuentra dentro del paréntesis es el número del casillero.
rbinom(15, 10, 0.10)
rbinom(15, 10, 0.10)

set.seed (001)
rbinom(15, 10, 0.10)

Ahora imaginemos que necesitamos generar 100,000 valores de una variable aleatoria con
función de distribución Uniforme[0,1] y además, se desea generar un histograma para éstos
datos:

set.seed(112358)
x=runif(100000)
hist(x, breaks=17, xlab="Valores Generados de una Uniforme", ylab="Frecuencia")

Ahora trabajemos con algunos ejemplos un poco más reales:

Ejemplo 1: Supongamos que nosotros queremos simular un conjunto de datos aleatorios


para el siguiente modelo lineal:

Donde y que y que

set.seed(002)
x = rnorm(100)
e = rnorm(100, 0, 2)
y = 0.5 + 2 * x + e
summary(y)
plot(x, y)

Actividad en clase: Ahora, del anterior modelo ¿qué pasaría si ? Muestre los
resultados gráficamente (histograma). Además, trace la curva de la distribución normal. ¿Se
observa algún ajuste de la distribución Normal a los datos?, es decir, si la función de
densidad se asemeja al histograma de los datos presentados.
117

Ejemplo 2: Suponga que queremos simular un conjunto de datos aleatorios para un modelo
Poisson donde

Y . Y además, asumamos nuevamente que

set.seed(1)
x = rnorm(100)
log.mu = 0.5 + 0.3 * x
y = rpois(100, exp(log.mu))
summary(y)
hist(y)

Actividad en clase: Trace la curva de la función de densidad normal con estos parámetros y
ver que tengan aspectos similares con el histograma de los datos.

Ejemplo 3: Una variable aleatoria X tiene distribución uniforme continua sobre el intervalo
[a, b] con a < b si su función de densidad está dada por:

[ ]

y se denotará por [ ].

De uno de los ejemplos realizados anteriormente, se observó que los datos provenientes de
una distribución [ ] entonces el histograma debería ser plano, similar a la función de
densidad teórica.

Para verificar lo anterior, simulemos cuatro muestras provenientes de la distribución U[1,3]


de tamaños 100, 500, 1000 y 10000 usando la instrucción runif, para luego graficar sus
correspondientes histogramas. Veamos:

set.seed(001)
n=c(100,500,1000, 10000)
par(mfrow=c(2,2))
for(i in 1:length(n)){
a=n[i]
hist(runif(a,1,3), main="Dist. Unifome con diferentes tamaños", xlab=a,
ylab="Frecuencia", col="lightyellow")
}
118

Ejemplo 4 [Para desarrollar en clase]: Descripción del problema.

El objetivo es abordar lo siguiente: La distribución exponencial se puede simular en R con


1
rexp(tamaño n, lambda). La media de distribución exponencial es y la desviación
𝜆
1
estándar Ahora, asumamos que lambda = 0.2 para todas las simulaciones. En esta
𝜆
simulación, se desea investigar la distribución promedio de 40 exponenciales ( 𝜆 = 0.2).

De acuerdo con lo anterior, se ilustrará mediante simulación e interpretación las propiedades


de la distribución de la media de 40 exponenciales ( 𝜆 = 0.2). Por lo tanto, usted debe:

a. Calcular la media de la distribución (datos simulados) y compararla con la media teórica


de la distribución.
b. Calcular desviación estándar de los datos y compararla con la desviación estándar
teórica de la distribución.
c. Interprete los resultados obtenidos en a) y b).
d. Demuestre que la distribución de los datos simulados es aproximadamente normal.
Interprete los resultados.
1 𝑠
e. Evaluar la cobertura del intervalo de confianza para : 𝑥̅ ± 1.96 , donde m es el
𝜆 √𝑛
tamaño muestral de los datos simulados. Interprete los resultados.

3.1.2. La función sample


La función sample es muy útil para efectuar simulaciones

sample(1:10, 6) # Extrae del vector 1:10, seis elementos al azar sin repetición
sample(1:10, 6, rep = T) # extrae del mismo vector 6 elementos en los que se
admite repetición.

Ejemplo práctico:

Para simular la tirada de un dado podemos utilizar

sample(1:6, 1)

Para simular la tirada de 4 dados, o de un mismo dado 4 veces, podemos utilizar

sample(1:6, 4, rep = T) # admitiendo repetición.

Si queremos simular la distribución de la suma de los números que salen al tirar 4 dados

E> simu.1 = sapply(1:10000, function(x) {


sum(sample(1:6, 4, rep =
T))
})
119

Donde, la función sapply aplica a un vector de tamaño 10000 una función sin nombre,
generando a su vez un vector de tamaño 10000. La función obtiene muestras con repetición
de tamaño 4 y, a continuación, suma los números de la muestra. Este proceso se repite 10000
veces. Para garantizar que los resultados son los mismos que los de esta práctica, nos servimos
de set.seed(100)

set.seed(100)
t <- sapply(1:10000, function(x) {
sum(sample(1:6, 4, rep = T))
})

y tabulamos los resultados con

table(t)

y podemos representar los resultados con un diagrama de barras.

barplot(table(t))
Ahora, Se podría haber procedido similarmente así:

x = runif(4, 0, 6) # genera 4 números aleatorios uniformemente distribuidos entre 0 y 6.


x
La función
ceiling(x)

Combinando las dos instrucciones, se pueden generar números aleatorios entre 1 y 6.


ceiling(runif(4, 0,6))

Con la siguiente instrucción podríamos conseguir

t = sapply(1:10000, function(x) {

sum(ceiling(runif(4, 0, 6)))

})

# transforma los valores anteriores en el menor entero no inferior al número (Digamos que
el número siempre se redondea por arriba).

lo mismo que lo anterior :


t = sapply(1:10000, function(x) {

sum(sample(1:6, 4, rep = T))

})
120

Ahora, Si lo que se quiere es simular el número de veces que sale un 6 en un dado (por poner
un ejemplo) en 10 tiradas. Entonces, dicho número, sigue una distribución binomial de
tamaño de 10 y probabilidad de éxito 1/6, por lo que se podría utilizar la función de R
“rbinom” para generar números aleatorios según esta distribución y realizar la simulación
más cómodamente.

Con la siguiente expresión se generan 12 números aleatorios en las condiciones antedichas

rbinom(12, 10, 1/6)

Lo anterior solo fue, para unos pocos, pero si ahora generamos 10000 números aleatorios
entonces:

set.seed(111)

t = rbinom(10000, 10, 1/6)

table(t)

barplot(table(t))

Otra simulación para la distribución normal, bajo la representación de un histograma y su


curva normal.

set.seed(111)

t = rnorm(100, 3, 2)

hist(t, freq = F) # donde, frec=F, obliga a representar densidades.

curve(dnorm(x, 3, 2), -4, 10, add = T)


# representa la curva normal de media 3 y desviación típica 2, para comparar.
# El parámetro add=T tiene el efecto de superponer la curva al histograma.
# Si no se pone, se borrará este.
121

Actividad en clase # 5:
1. Siguiendo el ejemplo anterior, muestre el efecto que tiene sumar dos distribuciones normales bajo
las siguientes condiciones: una de media 3 y desviación típica 2, y otra de media 5 y desviación típica
3.
2. Simula 10000 observaciones independientes de una variable aleatoria distribuida uniformemente
en el intervalo [3.7, 5.8].

a. Calcular la media, varianza y desviación típica de los valores simulados (Estima la media,
varianza y desviación típica de tal variable aleatoria uniforme) y compararlos con los
verdaderos valores de la distribución.
b. Estima la probabilidad de que tal variable aleatoria sea mayor o igual que 4 (Calcula la
proporción de valores que son mayores o iguales a 4) y compárala con el verdadero
valor.

3. Supongamos que el número de accidentes que ocurren en una carretera al año tiene una
distribución de Poisson de media 3.7.

a) Calcular la probabilidad de que en un año haya 6 accidentes.

b) Calcular la probabilidad de que un año haya menos de 2 accidentes

c) Calcular la probabilidad de que un año haya más de 8 accidentes.

d) Calcular el número máximo de accidentes que se producirán con probabilidad mayor o igual a 0.9.

e) Simula el número anual de accidentes que se producirán en un periodo de 20 años.


122

3.2. VERIFICACION DE ENUNCIADOS O RESULTADOS USANDO SIMULACION

El proceso de realización de simulaciones es a menudo muy repetitivo, por lo que


usaremos la sentencia for( ) que permite repetir una cierta operación un número de veces.

Recordemos su sintaxis:

for ( nombre in vector) { comandos }

Situación # 1.
𝑟
Dada una variable aleatoria X con distribución Hg(n, r, N), si se tiene que 𝑝 = 𝑁 ,con 0 < p < 1,
y 𝑁 → ∞, entonces, la función de densidad de X tiende a la función de densidad de una
distribución Bin(n,p). Demuestre que este enunciado es verdadero mediante simulación.

Solución:

La función de densidad para la distribución Binomial está dada por:

𝑛
𝑃(𝑥) = ( ) 𝑝 𝑥 (1 − 𝑝)𝑛−𝑥
𝑥
Y se denota como X ~ Bin(n,p)

La función de densidad para la distribución Hipergeométrica está dada por:

Donde:
 N = número de elementos en la población.
 r = número de elementos en la población que tienen una característica específica, por ejemplo, el
número de personas a favor de un producto particular.
 n = número de elementos en la muestra.
 x = número de elementos en la muestra que tienen dicha característica específica.
Además, x son valores enteros entre máx (0, n-N+r) y mín(r,n), y se denota como X ~ Hg(n,r,N).
123

Rutina:

Hg=function(x,n,R,N) {

x=c(max(0,30-50+20):min(50,30))

res=numeric(length(x))

for(i in 1:length(x)){

res[i]=choose(R,x[i])*choose(N-R,n-x[i])/choose(N,n)}

return(res)

par(mfrow=c(2,2))

plot(Hg(x,30,20,50),type="h",main="Hg(30,20,50)",xlab="x",ylab="f(x)")

lines(dbinom(x,n,20/50),col=2)

plot(Hg(x,30,50,80),type="h",main="Hg(30,50,80)",xlab="x",ylab="f(x)")

lines(dbinom(x,n,50/80),col=2)

plot(Hg(x,30,100,200),type="h",main="Hg(30,100,200)",xlab="x",ylab="f(x)")

lines(dbinom(x,n,100/200),col=2)

plot(Hg(x,30,300,1000),type="h",main="Hg(30,300,1000)",xlab="x",ylab="f(x)")

lines(dbinom(x,n,300/1000),col=2)

Actividad en clase: En la rutina anterior las curvas de distribución binomial no se generan para
poder hacer la comparación con la distribución hipergeométrica. Corrija esta dificultad.
124

Situación # 2.

Si 𝑈~𝑈(0,1) y F(x) es una función de distribución estrictamente creciente, entonces la


función de distribución de la variable 𝐹− (𝑈) está dada por F, donde 𝐹− denota la función
inversa generalizada de F dada por 𝐹− (𝑢) = í𝑛𝑓{𝑥: 𝐹(𝑥) ≥ 𝑢}.

El anterior resultado nos indica que si queremos simular n valores a partir de una cierta
distribución F, se debe, en primer lugar, hallar la función de distribución inversa
generalizada 𝐹− , y en segundo lugar, simular n observaciones de la distribución U(0,1) que
denotamos por 𝑢1 , … , 𝑢𝑛 . Finalmente, el anterior resultado garantiza que los valores
𝐹− (𝑢1 ), … , 𝐹 − (𝑢𝑛 ) provienen de la distribución F.

Por ejemplo, se desea simular 100 observaciones de la función de densidad 𝑓 (𝑥 ) = 𝑒 −𝑥 , esto


es la función de densidad de una distribución 𝐸𝑥𝑝(1). Demuestre a través del enunciado
inicial, que efectivamente los datos aleatorios provenientes de una distribución
exponencial so similares a la estructura de los datos de 𝐹− .

Rutina

set.seed(003)
n=100
u=runif (100)
f.d= rexp(100,1) # función de densidad
f.i= -log(1-u) # función inversa
par(mfrow=c(1,2))
hist(f.d,ylab="Frecuencia", main="f(x)", col=rainbow(8))
hist(f.i,ylab="Frecuencia", main="F-",col=rainbow(8))
125

Situación # 3.

Se desea comparar los valores estimados entre la media y la varianza muestral como
estimador de λ en muestras provenientes de dos distribuciones Poisson. La idea es simular
las dos distribuciones Pois(5) y Pois (15) con tamaño de muestra n = 5, . . . , 300 y en cada
muestra simulada, se calculan las dos estimaciones de momentos para la media y la varianza,
y se observa cuál es más cercano al valor verdadero del parámetro.

Rutina:

#####Para lambda = 5 ########

set.seed(123)
n=5:300
media.est=rep(NA,length(n))
var.est=rep(NA,length(n))
for(i in 1:length(n)){
x=rpois(n[i],5)
media.est[i]=mean(x)
var.est[i]=var(x)*(n[i]-1)/n[i]
}

#####Para lambda = 15 #######

media1.est=rep(NA,length(n))
var1.est=rep(NA,length(n))
for(i in 1:length(n)){
y=rpois(n[i],15)
media1.est[i]=mean(y)
var1.est[i]=var(y)*(n[i]-1)/n[i]
}
126

###### Gráfico - Lambda = 5 ######

par(mfrow=c(2,1))

plot(n,var.est,xlab="n",ylab="Estimación",main="PoblaciónP(5)",
type="l",col="blue",ylim=c(2,9))

abline(5,0)

lines(n,media.est,col="red")

legend(200,9.2,c("Media","Varianza"),lty=c(1,1),col=c("red","blue"),box.col=0)

###### Gráfico - Lambda = 15 ######

plot(n,var1.est,xlab="n",ylab="Estimación",main="Población P(15)",
type="l",col="blue")
abline(15,0)
lines(n,media1.est,col="red")

legend(200,45,c("Media","Varianza"),lty=c(1,1),col=c("red","blue"),box.col=0)

Actividad en clase: Repita en ejemplo anterior incluyendo los valores para λ = 30 y λ =


50. Interprete los resultados.
127

Continuación actividad en clase # 5

4. Una versión del teorema del límite Central dice que si X es una variable
aleatoria Poisson con parámetro λ, y

Entonces Z se aproxima a la normal estándar, si aumentamos λ. El siguiente código


simula un gran número de valores de Z para diferentes λ en el conjunto {1, 3, . . .,99} y
donde se construye un QQ- plot en cada caso:

for (m in seq(1, 100, 2)) {


z <- (rpois(20000, lambda = m) - m) / sqrt(m)
qqnorm(z, ylim = c(-4, 4), main = "QQ-plot")
qqline(z)
mtext(bquote(lambda == .(m)), 3)
}

Corre o ejecuta la rutina y observa cómo la distribución Z cambia al incrementar λ.

De lo observado anteriormente, ¿qué tan grande debería ser λ antes de que tus
datos se vean montados sobre la línea recta del QQ-plot para concluir que éstos se
aproximan a la distribución normal estándar?
128

___________________________________________________________________________________________

UNIDAD 4
_____________________________________________________________________________
___________________________________________________________________

ANÁLISIS E INTERPRETACIÓN DE ALGUNOS TOPICOS DE


ESTADÍSTICA DESCRIPTIVA, INFERENCIAL Y REGRESIÓN

Una adaptación del libro “Estadística básica con R y R – Commander”. Versión

febrero 2008. Autores: A. J. Arriaza Gómez, F. Fernández Palacín, entro otros .


http://knuth.uca.es/moodle/course/view.php?id=37

Bajo la autorización de:

Copyright c 2008 Universidad de Cádiz. Se concede permiso para copiar, distribuir y/o modificar este documento
bajo los términos de la Licencia de Documentación Libre de GNU, Versión 1.2 o cualquier otra versión posterior
publicada por la Free Software Foundation. Una traducción de la licencia está incluida en la sección titulada “Licencia
de Documentación Libre de GNU”.
129

4.1 Análisis Exploratorio de Datos bidimensionales

4.1.1. Análisis de relaciones entre dos atributos


Para analizar e interpretar la relación que existe entre dos variables categóricas ya sean
dicotómicos o politómicos es necesario tener a la mano una tabla de frecuencias conjunta. La
siguiente tabla muestra la estructura general que debe tener una tabla de doble entrada.

La tabla anterior muestra las distribuciones conjuntas y marginales de dos atributos A y B.


Donde A1, A2,…. Y B1, B2,…, son las clases de cada una de estas variables. Los nij representan las
frecuencias absolutas del par (Ai,Bj) y finalmente tanto la última columna como la última fila
representan las distribuciones marginales de los atributos A y B.
130

Ahora a manera de práctica analizaremos ciertas situaciones sobre la relación que existe entre
dos atributos. De aquí en adelante estaremos trabajando bajo el ambiente de R – Commander.

Recordemos a continuación la forma de invocar R-Commander ya sea en R-Gui o RStudio:


library(Rcmdr)

Nota Importante: Si por algún motivo uno cierra R-Commander y se desea volverlo abrir
nuevamente, se escribe lo siguiente en la consola:
Commander()

Ejemplo 1.
Del fichero de datos del libro http://knuth.uca.es/moodle/mod/url/view.php?id=1125
descargar el conjunto de datos <titanic.dat> e importarlo en Rcmdr, en el que aparecen las
variables Class, Sex, Age y Survived, que aportan información, respectivamente, de las 2201
observaciones sobre la clase que ocupaba el pasajero, su sexo, edad y si sobrevivió o no al
naufragio del famoso transatlántico. En concreto, se intentará establecer una posible asociación
entre la supervivencia y la clase en la que viajaban los pasajeros del Titanic.

a. Construir una tabla de doble entrada para las variables relacionadas, muestre la tabla de
porcentajes totales y además de información sobre el grado de relación entre los
atributos, a través de la prueba de independencia de chi-cuadrado. Establezca las
hipótesis nula y alternativa e interprete los resultados a un nivel de significancia del 5%.

Intrucciones de invocación: Datos  Importar datos  desde archivo de texto,


portapapeles, URL…  (Dar un nombre al conjunto de datos y Seleccionar las opciones de
acuerdo a las caracterìsticas de los datos a importar)

Instrucciones de anàlisis: Estadìsticos  Tablas de contingencia  Tabla de doble


entrada…  En datos: Variable fila  Survived. Variable columna:  Class.
En Estadìsticos: Porcentaje totales y Test de independencia Chi – cuadrado.

b. Determine e interprete la intensidad de la relación entre ambas variables mediante el uso


del coeficiente de contingencia corregio de Karl Pearson.

√ √
Donde : es el valor del estadìstico de prueba
n : es el tamaño de la muestra
k: es el menor número entre el número de filas y columnas.

Valores cercanos del coeficiente de a 0 indica que no hay ningún tipo de relación
entre las variables y valores cercanos a 1 indica que hay una fuerte relación entre las
variables.

Instrucciones de anàlisis: Escribir la ecuación Directamente en el R Script.


131

c. Visualice la relación que hay entre las variables, por ejemplo mediante un diagrama de
barras de la variable supervivencia según la clase de los pasajeros. Interprete los
resultados.

Instrucción R Script:
Tabla = xtabs(~Survived+Class, data=titanic)
barplot(Tabla, xlab="Clase", ylab="Frecuencia", beside=TRUE,col=cm.colors(2))
grid(0,20,col="lightgrey")
legend(locator(1),c("No superviviente", "Superviviente"),pch= c(15,15,15),
col=cm.colors(2))

d. Construya nuevamente el diagrama de barras usando las frecuencias relativas o


porcentajes de supervivencia respecto a cada clase. Interprete los resultados.

Instrucción R Script:
Tabla.rel = colPercents(Tabla)
Tabla.rel = Tabla.rel[1:2,1:3]
Tabla.rel
barplot(Tabla.rel, xlab="Clase", ylab="Freceuncia Relativa (%)",
beside=TRUE,col=cm.colors(2))
grid(0,20,col="lightgrey")
legend(locator(1),c("No superviviente", "Superviviente"),pch= c(15,15,15),
col=cm.colors(2), bty="n")

Nota : bty define si se desea la leyenda con marco “o” o sin marco “n”.

e. Construya un gráfico para la tabla de contingencia, mediante el gràfico de mosaico para


analiza todos los atributos del fichero Titanic. Interprete los resultados.

Instrucción R Script:

Tabla
mosaicplot(Tabla,main="Relaciòn entre no Sobrevivientes y \n sobrevivientes del
Titanic",col=c("blue","green"),xlab="Sobrevivientes",ylab="Tipo de Clase del
pasajero")

Actividad en clase: Explore la función assoc() del paquete {“vcd”} (Meyer y col. 20012) que
también permite representar gráficamente tablas de contingencia 2xk y compare sus resultados con
los obtenidos con el del gràfico de mosaico.
132

4.1.2. Análisis de relaciones entre dos variables de medida

A diferencia del estudio anterior, aquí se abordará la relación entre dos variables numéricas
(medibles). Éste análisis se hará a través de una función de ajuste, en otras palabras a través de
un modelo de regresión donde veremos la relación que existe entre la variable independiente o
explicativa y la variable dependiente o explicada.

En la mayoría de los casos el conjunto de datos contiene muchas variables numéricas, donde el
investigador desea estudiar el comportamiento de una de ellas sobre la que tiene un interés
especial (dependiente) a partir del conocimiento de un conjunto del resto de variables
(independientes).

Lo primero que se debe hacer para abordar un buen análisis de los datos es representar los datos
mediante un diagrama de dispersión, para observar que tipo de relación existe entre Y/ X, es
decir, si es una función lineal, una parábola, una función exponencial o una función potencia, etc.

Por ejemplo, la siguiente figura ilustra lo dicho para el caso lineal Y = a + bX, donde a representa
el punto de corte de la recta con el eje Y y b el incremento–decremento de Y para un incremento
unitario de X.
133

Después de haber creado el diagrama de dispersión y obtener el modelo de regresión, es


importante también hacer los siguientes análisis estadísticos: (a) Predicciones, (b) Análisis
de bondad de ajuste, (c) Análisis de residuos del modelo y (d) mejora del modelo.

Ahora mostraremos un ejemplo donde podamos aplicar todos estos conceptos sobre el ajuste
lineal.

Ejemplo 2: Analizaremos la relación que existe entre las variables peso y altura del conjunto
de datos peso_altura el cual se encuentra en la dirección URL
http://knuth.uca.es/repos/ebrcmdr/bases_datos/, en el que aparecen, entre otras variables,
el sexo, peso y altura de un grupo de personas. Como se ha indicado anteriormente es
necesario establecer qué variable será la explicada y cuál la explicativa. Dado que se trata de
un ejemplo y que no se cuenta con elementos adicionales para avalar la decisión, se decide
explicar el peso (y) en función de la altura (x). Todo este proceso se realizará en el ambiente
de Rcmdr.

a. Antes de abordar el análisis bidimensional peso vs altura, construya un histograma


para cada una de las variables para ver la forma de su distribución. Agregue la curva
de la distribución normal. Interprete los resultados.

library(Rcmdr) # Para entrar al ambiente de Rcmdr, estando en el R básico.

Instrucciones para cargar conjunto de datos “peso_altura” dentro de Rcmdr:


Datos → Importar datos → Desde archivo de texto, portapapeles o URL → Leer conjunto
de datos desde paquete adjunto → “Escoger opciones de acuerdo al conjunto de datos”
→ Aceptar.

Instrucciones para construir el Histograma:


Gráficas → Histograma → “Seleccionar dentro de Datos la variable de interés” →
“Revisar dentro de Opciones si se desea modificar los que van por defecto” →
Aceptar.

Modifique el argumento color por: col=heat.colors(11)

b. Con el fin de decidir qué tipo de función se ajusta más a los datos, elabore un
diagrama de dispersión para las variables altura vs peso. Interprete los resultados.

Instrucciones para construir el diagrama de dispersión:


Gráficas → Diagrama de dispersión → “Seleccionar dentro de Datos la variable x y la
variable y” → “Dentro de Opciones en opciones de gráfica, deshabilitar todo excepto
Línea de mínimo cuadrado, en Identificar observaciones dejarlo como automáticamente →
Aceptar.
134

c. Verifique la existencia de una alta o baja correlación entre las variables, usando el
coeficiente de correlación lineal de Pearson. Interprete los resultados.

Instrucciones en Rcmdr:
Estadísticos→ Resúmenes → Test de correlación → Escoger el par de variables a
probar, luego seleccionar el tipo de correlación y finalmente el tipo de hipótesis
nula → Aceptar.

d. Realice nuevamente un diagrama de dispersión, pero ahora separado por grupos


(para este caso la variable “sexo”). Interprete los resultados.

Instrucciones para construir el diagrama de dispersión separado por Grupo:


Gráficas → Diagrama de dispersión → “Seleccionar dentro de Datos la variable x y la
variable y” → Dentro de Opciones en opciones de gráfica, deshabilitar todo excepto
Línea de mínimo cuadrado, en Identificar observaciones dejarlo como automáticamente →
Dentro de Gráfica por grupos, seleccione la variable grupo deseada (por ejemplo. Sexo)
→ Aceptar.

e. Ahora, verifique nuevamente la correlación entre las variables peso – altura pero
ahora para cada sexo. Interprete los resultados.

Instrucciones antes de calcular las correlaciones por separado en Rcmdr:


Datos→ Conjunto de datos activos → Filtrar el conjunto de datos activo..... tomando
como expresión de selección SEXO==‘‘Mujer’’ y darle un nombre al nuevo conjunto de
datos para la muestra femenina y lo mismo sucede con SEXO==‘‘Varón’’ para la
masculina → Aceptar.

Luego, para calcular las correlaciones se siguen los mismos pasos que en el punto c.

f. Calcule el modelo de regresión estimado tanto para los varones como para las
mujeres. Interprete los resultados.

Instrucciones en Rcmdr:
Estadísticos→ Ajuste de modelos → Regresión lineal... se elige PESO como variable
explicada y ALTURA como variable explicativa → Aceptar.

g. Calcule los valores ajustados por el modelo.

Instrucciones en Rcmdr:
Modelos → Selecciona el modelo activo.... se escoge el modelo → Aceptar → Añadir
las estadísticas de las observaciones a los datos... y se marcan las opciones deseadas,
en este caso Valores ajustados y residuos.

Verificar que efectivamente se incluyeron los valores anteriores dentro del conjunto
de datos inicial, haciendo click en visualizar conjunto de datos.
135

h. Para realizar predicciones para cualquier valor de X, se necesita crear previamente un nuevo
conjunto de datos, que en este caso se podría llamar pred y que contendrá una variable cuyo
nombre se hace coincidir con el nombre de la variable independiente del modelo:

Instrucciones dentro de la ventana de instrucciones o R Script:

pred = data.frame(ALTURA=c(180.3,184.7,193.1,197.0,201.8))
peso.p = predict(RegModel.1,pred) # predict(nombreModelo , pred)
pred = data.frame(pred,peso.p)
pred = round(pred,1)
pred

i. Calcule los valores residuales tanto tificados como estudentizados por el modelo.

Instrucciones en Rcmdr:

Modelos →Selecciona el modelo activo → Añadir las estadísticas de las observaciones a


los datos... y se marcan las opciones deseadas, en este caso Residuos y Residuos
Studentizados.

j. Residuos indexados. Detecta sobre todo problemas relacionados con la influencia que
valores previos de la variable X ejercen sobre los posteriores. Ocurre sobre todo cuando
la variable independiente es el tiempo, desde el punto de vista estadístico se dice que
existe un problema de autocorrelación y la solución pasa por enfocar el tema desde la
óptica de las series temporales. El gráfico de los residuos indexados se obtiene desde

Instrucciones en Rcmdr:
Gráficas → Gráfica secuencial... seleccionando la variable residuals.RegModel.1, la opción
Identificar puntos con el ratón y por ´ultimo elegir la representación por puntos.

k. Residuos estudentizados frente a valores ajustados. Es probablemente el gráfico que


proporciona más información sobre la calidad del ajuste realizado, informando sobre la
falta de linealidad de la relación, la presencia de valores atípicos, la existencia de terceras
variables que aportarían información relevante sobre Y, etc.

Instrucciones en Rcmdr:

Gráficas → Diagrama de dispersión..., tomando fitted.RegModel.1 como variable


explicativa y rstudent.RegModel.1 como variable explicada.
136

l. Obtenga los valores influyentes mediante el cálculo de la distancia de Cook y su gráfico


respectivo. Interprete los resultados.

Instrucciones en Rcmdr:

Modelos → Selecciona el modelo activo → Añadir las estadísticas de las observaciones a


los datos... y se marcan las opciones deseadas, en este caso Distancia Cook.

Gráficas → Gráfica secuencial... seleccionando la variable cookdistance.RegModel.1, y la


opción Identificar puntos con el ratón.

m. Obtenga la gráfica de potenciales hat (x) frente a residuos estudentizados (y), donde cada
observación está identificada por un círculo cuyo diámetro es proporcional a su distancia
de cook, sintetiza toda la información a tener en cuenta a la hora de identificar los puntos
influyentes. Interprete los resultados.

Instrucciones en Rcmdr:

Modelos → Selecciona el modelo activo → Añadir las estadísticas de las


observaciones a los datos... y se marcan las opciones deseadas, en este valores Hat.

La gráfica ha de ser creada de dos maneras:

1. Gráficas → Diagrama de dispersión → “Seleccionar dentro de Datos la variable x y la


variable y” → “Dentro de Opciones en opciones de gráfica, deshabilitar todo excepto
Línea de mínimo cuadrado, en Identificar observaciones dejarlo como automáticamente y
aumentar el Número de puntos a identificar (6) → Aceptar.

2. Modelos → Gráficas → Gráfica de influencia. (Modo directo)


137

Actividades de práctica:

1. Repita nuevamente todos los análisis anteriores pero ahora para el grupo de las mujeres.

2. Reproduzca el ejemplo 3.4 de la página 77 del texto “Estadística básica con R y R –


Commander”, como ilustración en la realización de un ajuste de tipo polinómico.

3. Desarrolle el ejercicio 3.2 de la página 82 del texto “Estadística básica con R y R –


Commander”.
138

4. 2 Inferencia clásica en poblaciones Normales y no Normales.

4.2.1. Inferencia clásica en poblaciones normales

En la primera parte se trabajó solo en la exploración de un conjunto de datos donde se han


descrito sus principales características. Ahora, en esta segunda se hará un análisis inferencial, el
cual parte de una muestra pequeña y representativa, donde se tiene intenciones de conocer las
principales características de la población, tal como la media, la desviación estándar, su
estructura de probabilidad etc.

Desde un punto de vista intuitivo, parece razonable que si efectivamente la muestra representa
bien a la población, los parámetros muestrales sean muy parecidos a los poblacionales y aunque
ciertamente este enfoque de estimación puntual es básicamente correcto, adolece de ciertas
carencias que lo convierten sólo en una parte del proceso inferencial.

El análisis inferencial se conseguirá a partir desde dos puntos de vista: mediante la construcción
de intervalos de confianza y la realización de contrastes de hipótesis.

Ejemplo 1. Se considera que el fichero de datos peso_altura.dat es una muestra aleatoria simple
de la población adulta de un municipio andaluz. Dicha muestra se utilizará para estudiar los
valores medios del peso y la altura de la población. Lo siguiente son las instrucciones de trabajo:

a. Realice un resumen numérico. Interprete los resultados


b. Elabore un intervalo de confianza del 95% para la altura de los hombres.
c. Realice una prueba de hipótesis a un nivel de significancia del 1%, donde

H0: µ = 175

H1: µ ≠ 175

Interprete los resultados.

d. Realice ahora el siguiente contraste a un nivel de significancia del 1%, donde

H0: µ ≥ 175

H1: µ < 175

Interprete los resultados.


139

Ejemplo 2. Para el caso de muestras independientes se usará el fichero parque eolico.dat, el


cual se encuentra en la dirección URL http://knuth.uca.es/repos/ebrcmdr/bases_datos/, que
contiene datos de la velocidad del viento, registrados durante 730 horas de forma simultánea, en
dos localizaciones alternativas (Parque1 y Parque2). El objetivo aquí es de establecer la
localización más aconsejable para la instalación de un parque de producción de energía eólica.
Naturalmente se escogerà aquella que en promedio produzca mayores velocidades.

Nota: Para un trabajo más preciso, puede recurrir a las instrucciones de la página 121 – 123.

Actividades de práctica:
1. Reproducir el ejemplo 5.4 de la página 123, del texto “Estadística básica con R y R –
Commander” para el caso de muestras pareadas.

2. Realice los ejercicios 5.2 y 5.6 de la página 125 -127, del texto “Estadística básica con R y R
– Commander”.
140

4.2.2. Inferencia no paramétrica.


En esta parte se trabajará sobre pruebas de bondad de ajuste (en especial sobre la Distribución
Normal) y además análisis de datos cuando se desconoce qué tipo de distribución, tiene cierto
conjunto de datos. Mediante pruebas de hipótesis podremos evaluar la bondad de ajuste de los
datos.

Para realizar contrastes específicos de normalidad se puede emplear la prueba de Shapiro –


Wilk, y un par de pruebas genéricas para evaluar la bondad del ajuste, uno para cuando los datos
son continuos, el de Kolmogorov-Smirnov, y otro para variables categóricas, la prueba de la
Chi – cuadrado. En el caso de contrastes de normalidad, se recomienda el uso del test de
Shapiro-Wilk para muestras pequeñas n ≤ 50, mientras que si las muestras son grandes es
preferible utilizar el test de Kolmogorov-Smirnov, salvo que los datos vengan dados en una
distribución de frecuencias por intervalos donde se empleará la de Chi – Cuadrado.

Ejemplo 1. El archivo de datos que se utilizará en este ejemplo es el de caracoles.dat, el cual se


encuentra en la dirección URL http://knuth.uca.es/repos/ebrcmdr/bases_datos/ que incluye las
mediciones de dos variables, diámetro de las conchas (mm) y separación entre las espirales
(μm), para un conjunto de 20 individuos adultos de una especie de caracoles. Lo que se desea
aquí es verificar si la variable diámetro de las conchas, provienen de una distribución normal.

Solución

Debido a que el tamaño muestral está por debajo de 50, la literatura recomienda contrastar la
hipótesis de normalidad mediante la prueba de Shapiro – Wilk.

Instrucciones en Rcmdr:

Estadístico → Resú menes → Test de normalidad de Shapiro – Wilk...

Ejemplo 2. Verifique la normalidad de la variable peso del conjunto de datos peso_altura.dat


mediante la prueba de Kolgomorov – Smirnov.

Solución

Nota: La razón de de emplear la prueba de KS se debe a que el tamaño de la muestra es mayor de


50.

Instrucciones en Rcmdr:

En la ventana de instrucciones se debería escribir lo siguiente (forma general):

ks.test (vector de la variable, pnorm, valor media, valor desv. Típica)


141

Importante: El test Chi-cuadrado permite contrastar la hipótesis de independencia entre dos


atributos organizados en tabla de contingencia.

Ejemplo 3. Analice la relación entre el nivel de estudios del padre y la orientación del alumno
hacia las ciencias en un determinado instituto de bachillerato. Se cuenta para ello con la
información obtenida en el centro. Use un nivel de significancia del 10%.

Orientaciòn
Estudios Padre Orientado No orientado
Ninguno 23 18
Bàsico 12 42
Medio 34 16
Superior 32 27

Solución

Instrucciones en Rcmdr:

Estadístico → Tablas de contingencia → Introducir y analizar un tabla de doble entrada... aquí


realizar los cambios necesarios a dicha tabla.

Importante: Para el caso de tablas 2×2 se aplica el test exacto de Fisher, aunque existe la
alternativa de aplicar el test Chi-cuadrado con la corrección de Yates. Para aplicar esta
corrección bastaría especificar, correct=TRUE, en la instrucción de dicho test.

Ejemplo 4. En el conservatorio de música de una ciudad se pretende estudiar la relación


existente entre el sexo del alumnado y su afición por los instrumentos de viento. Para ello,
observados los 482 estudiantes se tiene:

Tipo de Aficiòn
Gènero Aficionado No aficionado
Hombre 150 97
Mujer 123 112

Use un nivel de significancia del 5%.

Ejemplo 5. Se estudiará mediante el test de Wilcoxon para muestras independientes si las dos
ubicaciones del parque eólico, cuya información se encuentra en el archivo eólico apilado.dat,
tienen la misma potencialidad eólica.

Solución.

Instrucciones en Rcmdr:

Estadísticos → Test no paramétricos → Test de Wilcoxon para dos muestras... y seleccionar


velocidad y luego parque.
142

Actividades de práctica:
1. Reproducir los ejemplo 6.12 y 6.13 de la página 140, del texto “Estadística básica con R y R
– Commander” para el caso de una muestra y muestras pareadas.

2. Realice los ejercicios 6.1, 6.2, 6.3, 6.5 y 6.10 de la página 142 -143, del texto “Estadística
básica con R y R – Commander”.
143

4.2.3. Regresión logística

A veces se desea modelar resultados binarios, es decir, variables que pueden tener sólo dos
valores posibles: enfermo o no enfermo, fumador o no fumador y así sucesivamente. Por ejemplo,
se quiere describir el riesgo de contraer una enfermedad en función de diversos tipos de
exposiciones.

Un Análisis de regresión logística pertenece a la clase de modelos lineales generalizados. Estos


modelos se caracterizan por su distribución de respuesta (para este caso la distribución
binomial) y una función de enlace, que transfiere el valor medio con una escala en la que la
relación con las variables de antecedentes se describe como lineal y aditiva. En un análisis de
regresión logística, la función de enlace es logit p = log [p / (1 - p)].

En R los modelos lineales generalizados son trabajados por la función glm. Esta función es muy
similar a lm, que hemos utilizado en algunas ocasiones para regresión lineal. Las dos funciones
utilizan esencialmente los mismos argumentos, sin embargo glm requiere ser especificada con
respecto al modelo lineal generalizado que se desea en el momento. Esto se hace a través del
argumento “family”. En este caso para especificar un modelo binomial con enlace “logit”, se
necesitaría escribir en R family = binomial (“logit”).
144

Ejemplo: Realizaremos un estudio concerniente a problemas de hipertensión en un cierto grupo


de pacientes en una clínica, teniendo en cuenta tres tipos de factores que afecta a tal enfermedad
(fumador, obesidad y ronquera).

Fuente bibliográfica: Introductory Statistics with R Second edition, by Peter Dalgaard pag. 229.

Solución:

En primera instancia se ingresan los datos en el entorno de R:

no.si = c("No", "Si")

fumador = gl(2, 1, 8, no.si)

obesidad = gl (2, 2, 8, no.si)

ronquera = gl(2, 4, 8, no.si)

n.total = c(60, 17, 8, 2, 187, 85, 51, 23)

n.hiper = c(5, 2, 1, 0, 35, 13, 15, 8)

data.frame (fumador, obesidad, ronquera, n.total, n.hiper)

Ahora como la variable de respuesta no se muestral directamente, entonces se requiere hacer


una nueva tabla especificando únicamente dos vectores (el número de hipertensos y el número
de sanos)

hiper.tabla = cbind(n.hiper, n.total-n.hiper)

hiper.tabla

En este caso, la primera columna se considera el "éxito", mientras que la otra se considera el
"fracaso". Ahora vamos a correr la regresión logística:

glm(hiper.tabla~fumador + obesidad + ronquera, family = binomial ("logit"))

Podríamos haber especificado el mismo modelo sin incluir "logit" en la línea de comandos. Esto
se debe a que "logit" es el valor predeterminado para el comando binomial. Es decir que, se
podría haber especificado simplemente:

glm(hiper.tabla~fumador + obesidad + ronquera, binomial)


145

Una alternativa para el modelo logístico anterior:

Dalgaard señala una segunda forma de especificar el modelo logístico. En lugar de producir dos
vectores columna de "éxito" y "fracaso", se puede especificar el porcentaje de éxitos. Para
obtener la proporción de los datos actuales, hay que calcular la razón de n.hiper/n.total.
Dalgaard define esto como "prop.hiper":

prop.hiper = n.hiper/n.total

Por lo tanto el modelo de regresión logística es:

glm.hiper = glm(prop.hiper~fumador + obesidad + ronquera, binomial, weights = n.total)


glm.hiper

Como se puede observar, el resultado es el mismo que cuando especificamos el modelo con dos
vectores columna. Ahora, para obtener la tabla de los coeficientes de la ecuación logística, se
requiere escribir el comando:

summary(glm.hiper)

Ahora, sería interesante observar la correlación que existe entre los parámetros estimados, el
cual se puede lograr incluyendo el argumento corr = T dentro de la función summary

summary(glm.hiper,corr=T)

La prueba z en la tabla de los coeficientes de regresión muestra que el modelo puede ser
simplificado removiendo la variable “fumador”.

glm.hiper = glm(hiper.tabla~obesidad+ronquera,binomial)
summary(glm.hiper)

Nótese la diferencia que hubo al extraer la variable fumador con respecto al modelo inicial. ¿A
qué conclusiones llegó?
146

_______________________________________________________________________________________

UNIDAD 5
_______________________________________________________________
______________________________________________________________________________________

EL MÉTODO BOOTSTRAP Y SUS APLICACIONES

5. 1 Introducción
El desarrollo en computadores y softwers de los últimos años ha abierto las puertas a
nuevos métodos estadísticos más potentes y precisos, destacando todos aquellos que
emplean el remuestreo como principal herramienta de análisis. Dentro de este grupo,
aparece el bootstrapping o bootstrap que fue propuesto y estudiado inicialmente por
Bradley Efron y Robert Tibshirani (1979) como un método para la aproximación de la
distribución de muestreo de un estadístico. En cuanto a esto, la inferencia estadística
tradicional emplea ciertas suposiciones acerca de la distribución poblacional para
determinar matemáticamente la distribución muestral de un estadístico. De este modo,
cuando la población se distribuye N(µ,σ2), y se estima el valor de la media muestral ( ̅ y la
varianza muestral ( , las cuales se distribuyen normalmente con media µ y varianza y
con (n-1) grados de libertad, respectivamente. De igual manera, da por hecho el
cumplimiento del Teorema de Límite Central para tamaños de muestra suficientemente
grandes, sin definir con precisión lo que "suficientemente grande" significa. En muchas
ocasiones por ejemplo, los sesgos que se observan en la distribución poblacional, se
transfieren a la distribución de los estadísticos incluso con tamaños de muestra del orden
de 1000.

Los métodos de remuestreo, por su parte, presentan varias ventajas. Primero, son más
flexibles en lo que referente a supuestos acerca de la población y permiten además, estimar
la distribución de un estadístico de manera empírica. Segundo, no exigen de tamaños de
muestra excesivamente grandes para ser precisos y confiables (en general se recomienda
un tamaño de muestra mínimo de 50). Tercero, tienen magnitudes de sesgo
significativamente más pequeñas que otros modelos de inferencia. Cuarto, son más fáciles
de comprender y aplicar debido a su mecanicidad y que principalmente emplean tecnología
de softwares. Finalmente, son menos costosos y en la mayoría de las veces, más rápida y
efectiva que otros.
147

Esta técnica de remuestreo se emplea cada vez más en estadística gracias a que los
programas computacionales como R, ya que de manera manual sería casi imposible o
extremadamente tedioso hacer estimaciones cuando el tamaño de la muestra sea muy
pequeño o la distribución de los datos sea muy sesgada, con el fin de hacer estimaciones de
parámetros a través de intervalos de confianza y hacer pruebas de hipótesis.

¿Cómo funciona el Bootstrapping?

El método de bootstrapping surge de una muestra aleatoria de tamaño n que se toma de una
población con parámetro Ѳ. A partir de este punto, la implementación general se realiza
siguiendo los pasos detallados a continuación:

1) Crear B muestras nuevas a partir de la muestra original utilizando para esto,


muestreo con reemplazo. Las muestras generadas se denominan Muestras
Bootstrap y son de tamaño n al igual que la original.

2) Calcular el estadístico de interés estimado Ѳi de cada muestra bootstrap. Luego,


definir la distribución de los valores estimados creando así la Distribución
Bootstrap.

3) Utilizar la Distribución Bootstrap considerando que ésta contiene información


relevante en cuanto a la forma, centro y dispersión de la distribución muestral del
estadístico.

Nótese que mediante este método se genera una analogía importante que facilita la
comprensión del modelo: "la muestra aleatoria es a la población así como la muestra
bootstrap es a dicha muestra aleatoria".

El siguiente diagrama captura la esencia de la técnica de remuestreo Bootstrap:

Fuente: http://www.scalaformachinelearning.com/2016/05/bootstrapping-by-resampling-with.html
148

Limitantes de la Técnica Bootstrap:

Es muy importante resaltar que esta técnica depende estrictamente de la muestra observada
que se extrajo de dicha población. Así que, es crucial la calidad de la muestra original. Este
método se vería afectado si la muestra no se ha extraído a través de un procedimiento
aleatorio simple y si la muestra es demasiado pequeña, por lo que se podría cuestionar la
información obtenida debido a esta técnica de remuestreo. Sin embargo, ante estas
circunstancias se puede afimar que el método bootstrap, permite “extraer lo máximo” a partir
de la poca información disponible.

Ejemplo Ilustrativo # 1.

Suponga que usted como estadístico


desea saber cuál es el consumo de alcohol
en un grupo determinado de personas
que viven cerca de su barrio. Asumiendo
que ha evaluado a solo 20 individuos en
donde ha calculado su consumo de
alcohol en gramos semanales. Los
resultados se muestran a continuación:

(GRAMOS DE ALCOHOL EN LA SANGRE - GOOGLE SEARCH)

8.99 7.90 1.03 7.86 10.41 1.43 1.92 0.34 11.93 8.14
3.77 10.96 3.11 0.11 5.00 1.86 5.52 4.27 4.77 18.22

De lo anterior pretenda hacer un análisis estadístico descriptivo, ya sea en RGui o Rcmdr:

a. En primera instancia calcule la media y la mediana para estos valores y construya


un histograma, diagrama de cajas y bigotes o un QQPlot para observar la forma de
su distribución. Interprete los resultados.

b. Debido a los resultados obtenidos del inciso a., estime el valor de la mediana en la
población. Sin embargo, existe un gran problema, los datos son muy pocos y con un
sesgo bastante pronunciado, no se puede hacer inferencia estadística, por ejemplo
calculando un intervalo de confianza para la mediana ¿Qué se puede hacer para
mejorar esta situaciòn?

Nota: Hay que aclarar que no es posible buscar más individuos de la población por
sobrecostos, tiempo de ejecución y falta de coolaboración.

c. Dada las condiciones anteriores, ha pensado en aplicar la técnica de remuestreo


bootstrap. Asi, que ejecute los pasos mencionados previamente para su
funcionamiento:

 Obtenga por ejemplo como mínimo, 1000 muestras con reposición de la


muestra original o inicial.
 Calcule la mediana de las 1000 muestras.
 Construya uno método gráfico para mostrar la forma de su distribución.
Interprete los resultados.
 De ajustarse a una normal. Construya un intervalo de confianza del 95%
para hacer la estimación poblacional de la mediana. Use el método de la
aproximación de los percentile para esta parte; es decir, calcule el percentil
2.5 y el percentil 97.5. Interprete los resultados.
149

 Otra forma de calcular un I.C, es empleando el famoso TLC, el cual por


incumplimiento de supuestos no se puede aplicar con los datos originales,
pero si con los datos bootstrap. Interprete los resultados.

Desarrollo: Salida en Rmarkdown (RStudio).

consumo=c(8.99,7.90,1.03,7.86,10.41,1.43,1.92,0.34,11.93,8.14,3.77,10.96,3
.11,0.11,5.00,1.86,5.52,4.27,4.77,18.22)
alcohol=data.frame(consumo)
summary(alcohol$consumo)

## Min. 1st Qu. Median Mean 3rd Qu. Max.


## 0.110 1.905 4.885 5.877 8.353 18.220

# [ a ] -------------------------------------------

par(mfrow=c(2,2))
hist(alcohol$consumo,col="lightgreen",main="Distribuciòn del consumo del
alcohol",
ylab="frecuencia",xlab="Consumo(gramos)")
boxplot(alcohol$consumo,horizontal =
TRUE,col="lightgreen",main="Distribuciòn del consumo del
alcohol",ylab="frecuencia",xlab="Consumo(gramos)")
qqnorm(alcohol$consumo,col=3)
qqline(alcohol$consumo,col=2)

# [ c ] -------------------------------------------

library(plyr)
tabla=rdply(1000,data.frame(mediana=median(sample(alcohol$consumo,replace=
T))))
head(tabla)

## .n mediana
## 1 1 6.43
## 2 2 4.02
## 3 3 3.44
## 4 4 5.26
## 5 5 4.27
## 6 6 6.43

# -------------------------------------------
par(mfrow=c(2,2))
150

hist(tabla$mediana,col="orange",main="Distribuciòn
Bootstrap",xlab="Medianas",ylab="Frecuencia")
boxplot(tabla$mediana,col="orange", main="Distribuciòn
Bootstrap",horizontal=T)
qqnorm(tabla$mediana,col=4)
qqline(tabla$mediana,col="red")

# -------------------------------------------
summary(tabla$mediana)

## Min. 1st Qu. Median Mean 3rd Qu. Max.


## 1.645 4.270 4.885 5.180 5.520 10.410

hist(tabla$mediana,col="orange",main="Distribuciòn
Bootstrap",xlab="Medianas",ylab="Frecuencia")
quantile(tabla$mediana,c(0.025,0.975))

## 2.5% 97.5%
## 2.515 8.020

abline(v=2.515,col="blue",lwd=2)
abline(v=8.020,col="blue",lwd=2)
151

# -------------------------------------------
lim.inf=4.885-abs(qnorm(0.025))*sd(tabla$mediana)
lim.sup=4.885+abs(qnorm(0.025))*sd(tabla$mediana)
cat("\n","IC.95%: (", lim.inf,",",lim.sup,")","\n","\n")

##
## IC.95%: ( 1.938239 , 7.831761 )
##
152

Ejemplo ilustrativo # 2:

El siguiente ejemplo se basa en la aplicación del método bootstrap al constraste de hipótesis


en la investigación educativa. Se realizò un estudio en el 2002, basada en una estrategia
docente utilizada en la enseñanza de los Mètodos Cualitativos de Investigación Educativa a
estudiantes de Pedagogìa (ver link: Gil J. y Jaen A. ). En este estudio, se quizo evaluar la
experiencia sobre los cambios de actitud hacia la investigación, en donde se utilizò una escala
de medición de actitudes hacia la investigación cualitativa, adminitrada antes y después de la
experiencia a fin de comprobar el modo en que podrían haberse modificado las actitudes de
partida en el grupo de alumnos que cursan la materia, que en este caso solo fueron 6
estudiantes matriculados. El instrumento constaba de 20 ìtems, en donde el alumno debía
manifestar su grado de acuerdo conforme a una escala de seis (6) puntos. El objetivo principal
de este estudio es la comparación entre la media alcanzada por el grupo de alumnos antes y
después de la experiencia, es decir, que se desea contrastar la hipótesis nula (Ho) en la
igualdad de medias antes y después de la experiencia, contra la hipótesis alternativa (H1) para
la diferencia de medias. Ver artículo completo: Javier Gil Flores.
Los resultados se muestran a continuación:

Antes Despuès
68 68
73 88
76 94
80 100
85 108
92

Dado que es el grupo es tan pequeño, el supuesto de normalidad no es viable y por lo tanto no
se puede hacer inferencia estadística con la estadística clàsica. Asì que la idea es construir un
modelo de distribución para valorar la diferencia de medias observada a través del método
Bootstrap.

# EJEMPLO 2
# ------------------------------
#AA: Actitud Antes
#AD: Actitud Despues
AA=c(68,73,76,80,85,92)
AD=c(68,88,94,100,108)
U=c(AA,AD)
library(plyr)
rem=rdply(5000,data.frame(dif=mean(sample(U,replace=T)[1:6])-
mean(sample(U,replace=T)[7:11])))
par(mfrow=c(2,2))
hist(rem$dif,col=heat.colors(10))
boxplot(rem$dif,col="orange", main="Distribuciòn Bootstrap",horizontal=T)
qqnorm(rem$dif,col=4)
qqline(rem$dif,col="red")
153

La distribución obtenida constituye una estimación por medio de Bootstrap de la distribución muestral
para el estadìstico diferencia de medias. Al contabilizar el número de veces que la diferencia de
medias sea mayor o igual al valor esperado ( y  x ) en las muestras originales, que es 12.6,
podríamos obtener la frecuencia relativa, que consideraremos como una aproximación a la
probabilidad de encontrar:

 y  x   12.6
* *

 y  x   12.6 
* *
#
PHo
5000

Donde, y : es la media de AD y
x : es la media de AA.

dif.med.or= mean(AD)-mean(AA)
n.exitos=length(rem$dif[rem$dif>=12.6])
prob=n.exitos/5000
prob

## [1] 0.0468

Como la probabilidad que se obtuvo fue de 0.0116 < nivel de signicancia = 0.05, se rechaza la
hipótesis nula y podríamos afirmar que existe una diferencia significativa a favor del segundo grupo,
es decir, que las actitudes de los alumnos hacia la investigación cualitativa son mejores tras la
experiencia realizada en el marco de la asignatura Mètodos Cualitativos de Investigaciòn Educativa.
154

Otros ejemplos de aplicación:

Ejemplo # 3: El siguiente caso representa el funcionamiento del método de bootstrapping.


La tabla 1 presenta una muestra de 24 determinaciones de cobre en harina integral en
partes por millón (ubicación dentro de R  chem {MASS})

a. En primera instancia calcule la media para estos valores y construya un histograma


para observar la forma de su distribución.

b. Ahora estime el valor de la media muestral mediante bootstrap. Para esto se ejecuta el
siguiente algoritmo en R usando B (no. de Bootstrap) = 1000:

library(MASS)
data(chem)
med=c()
for (i in 1:1000) {
m.boot=sample(chem,length(chem),replace=T)
m.med=mean(m.boot)
med=c(med,m.med)
}

c. Compare los dos resultados anteriores.


#Media Observada:
mean(chem)

## [1] 4.280417

#"Media Bootstrap:
mean(med)

## [1] 4.307058

#Distribución Observada:
hist(chem)
lines(c(mean(chem),mean(chem)),c(0,350),col="red")
155

#Distribución Bootstrap
hist(med)
lines(c(mean(chem),mean(chem)),c(0,350),col="red")
lines(c(mean(med),mean(med)),c(0,350),col="blue")

Del gráfico anterior, se observa la distribución de los datos bootstrap, en donde se


indentifica la posición de los dos estadísticos (media) tanto la original como la bootstrap,
manifestando valores muy similares.
156

La Distribución Bootstrap
Cuando se genera una distribución bootstrap, la cual posee características de forma, centro
y dispersión semejantes a la distribución muestral del estadístico Ѳ, es posible calcular los
siguientes estimadores bootstrap considerando los Ѳ*i obtenidos:

(a) Media o Promedio Bootstrap el cual es un indicador del centro de la distribución:


B

ˆ *

 
i
Eboot ˆ*  i 1

(b) Error Estándar Bootstrap el cual es un indicador de la dispersión de la distribución:

  1  B ˆ*
   
2
SEboot ˆ*   
B  1  i 1
i  Eboot ˆ*

(c) Sesgo Bootstrap el cual es indicador de la forma de la distribución:

 
biasboot ˆ*  Eboot ˆ*  ˆ 
Cada uno de estos valores es también un estimador de la media, la desviación estándar y el
sesgo del estimador muestral que se está estudiando.
157

Ejemplo 3 (cont.): Siguiendo con el ejemplo anterior de las determinaciones de cobre. Si


se calculan la media y la desviación estándar del promedio de los datos y se los compara
con los estimadores bootstrap se observa lo siguiente:

#Media Observada:
mean(chem)

## [1] 4.280417

#Media Bootstrap:
mean(med)

## [1] 4.30943

#SE Media Observada:


sd(chem)/sqrt(length(chem))

## [1] 1.081326

#SE Media Bootstrap:


sd(med)

## [1] 1.109134

#Sesgo Bootstrap:
mean(med)-mean(chem)

## [1] 0.02901292

Los resultados obtenidos permiten concluir que en efecto, los valores de las medias y las
desviaciones estándar son considerablemente cercanos. Además, el sesgo bootstrap indica la
existencia de la cola a la derecha lo suficientemente notoria.

Como se mencionó líneas arriba, la distribución muestral del estadístico en algunos casos
suele mantener el sesgo propio de la población. Esto limita el cumplimiento, y
consecuentemente, la aplicación del Teorema de Límite Central en la inferencia tradicional.
Mediante la distribución bootstrap, es posible verificar gráficamente la afirmación anterior.
De igual manera, se facilita la toma de decisiones correctivas que faciliten la convergencia a
la normalidad de la distribución de muestreo del estadístico. El siguiente ejemplo ilustra este
concepto.
158

Ejemplo # 4: La tabla de abajo presenta los precios en millones de pesos de una muestra
de tamaño 50, de propiedades en Barranquilla durante el presente año.

Dado que la muestra no discriminó por tipo de propiedades (comerciales, residenciales o


industriales), es esperable que la cola derecha sea mayor que la izquierda producto del
mayor valor de las localidades dedicadas al comercio.

a. Calcule la media para estos valores y construya un histograma para observar la


forma de su distribución.

prop=c(142,232,132.5,200,362,244.95,335,324.5,222,225,175,50,215,260,307,21
0.95,
1370,215.5,179.8,217,197.5,146.5,116.7,449.9,266,265,256,684.5,257,570,149.
4,
155,244.9,66.407,166,296,148.5,270,252.95,507,705,1850,290,164.95,375,335,9
87.5,
330,149.95,190)
mean(prop)

## [1] 329.2571

hist(prop,col=heat.colors(7))

b. Estimar el valor de la media muestral mediante bootstrap. Para esto se ejecuta el


siguiente algoritmo en R usando B = 1000:

med=c()
for (i in 1:1000){
m.boot=sample(prop,length(prop),replace=T)
m.med=mean(m.boot)
med=c(med,m.med)
}
159

c. Compare e interprete los resultados anteriores.


mean(med)

## [1] 329.8585

par(mfrow=c(2,2))
hist(prop,col=heat.colors(7))
qqnorm(prop,col="blue")
hist(med,col=rainbow(7))
qqnorm(med,col="red")
160

Algunas Aplicaciones en Inferencia


Intervalos de Confianza

Existen varias maneras de calcular Intervalos de Confianza cuando se emplea el método de


bootstrapping. La forma a emplear dependerá exclusivamente de la distribución bootstrap
resultante del proceso. Si la distribución mencionada no presenta un sesgo de considerable
magnitud y se observa una aproximación a la normal, se puede usar intervalos t o de
percentiles, en caso contrario es recomendable usar intervalos BCa.

Intervalos t

Cuando se observa que la distribución bootstrap se aproxima a una normal es posible


calcular un intervalo de confianza con nivel de significancia α mediante la siguiente fórmula:

(̂ ) ( )

Intervalos de Percentiles

De igual manera, es posible calcular un intervalo con nivel de significancia α de percentiles


en caso de una aproximación a la normal de la distribución bootstrap. Para hacerlo, se debe
encontrar los cuantiles α /2*100% y 1 − α /2*100%, los cuales corresponden a la cota
inferior y superior del intervalo respectivamente. A diferencia del caso anterior, este
intervalo de confianza no es balanceado. Una forma de verificar la validez de estos dos casos
presentados es comparándolos y observando su parecido. Si sus valores difieren de manera
considerable, entonces se deben descartar y se procede a utilizar alguna de las siguientes
opciones a continuación.

Intervalos BCa (de Sesgo Corregido y Acelerado por sus siglas en inglés)

Este tipo de intervalo realiza una corrección por el sesgo en el caso anterior. Se obtiene
siguiendo estos pasos:

(1) Calcular el primer factor de corrección z tal que para:


161

(2) Calcular el segundo factor de corrección a tal que para ̂ : Valor Jackniffe de i y el
promedio de todos ellos Θ−i :

(3) Calcular las cotas del intervalo con nivel de significancia α de la siguiente manera:

Para que el intervalo BCa sea suficientemente confiable es recomendable que el tamaño de B
sea de al menos 1000.

Ejemplo # 5: Para llevar a cabo este ejemplo y los siguientes, se considerarán las funciones
guardadas en el paquete "boot" de R. Retomando los datos del precio de las propiedades, se
calcularán los distintos tipos de intervalos de confianza estudiados.

# Instalando el paquete "boot"


# --> install.packages("boot",dependencies=T)
library(boot)

#Función para calcular la media:


med.boot=function(x,i){
mean(prop[i])
}

#Generación de muestras bootstrap:


boot.prop=boot(prop,med.boot,R=1000,stype="i")

#Intervalos al 95% de Confianza:


boot.ci(boot.prop,0.95)

## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS


## Based on 1000 bootstrap replicates
##
## CALL :
## boot.ci(boot.out = boot.prop, conf = 0.95)
##
162

## Intervals:
## Level Normal Basic
## 95% (239.7, 416.7) (229.0, 406.5 )
##
## Level Percentile BCa
## 95% (252.0, 429.5) (260.6, 443.5 )

## Calculations and Intervals on Original Scale

Los resultados obtenidos indican que la distribución bootstrap no se aproxima a una normal
dada la diferencia entre el intervalo normal y el de percentiles. Nótese además, que el
intervalo BCa presenta una cota superior mucho mayor debido al sesgo antes estudiado.

Ejemplo # 6: Los datos galaxies en la librería MASS muestran la velocidad en Km/seg de


distintas galaxias observables desde el hemisferio norte. Realice bootstrap con estos datos
para obtener información acerca de la varianza:

library(MASS)
data(galaxies)

#Se divide la velocidad por mil


gal=galaxies/1000
var.boot=function(x,i){
var(x[i])
}

#Bootstrap de la varianza de la velocidad


boot.gal=boot(gal,var.boot,R=500)
boot.gal

##
## ORDINARY NONPARAMETRIC BOOTSTRAP
##
##
## Call:
## boot(data = gal, statistic = var.boot, R = 500)
##
##
## Bootstrap Statistics :
## original bias std. error
## t1* 20.82789 -0.1734189 4.735574

# distribución de los datos


plot(boot.gal)
163

#Intervalos de confianza al 95%


boot.ci(boot.gal,0.95)

## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS


## Based on 500 bootstrap replicates
##
## CALL :
## boot.ci(boot.out = boot.gal, conf = 0.95)
##
## Intervals :
## Level Normal Basic
## 95% (11.72, 30.28 ) (10.66, 29.34 )
##
## Level Percentile BCa
## 95% (12.31, 31.00 ) (13.16, 34.74 )
## Calculations and Intervals on Original Scale

Importante: En este ejemplo notará que el BCa resulta ser un intervalo más adecuado
dada la cola derecha que presenta la distribución bootstrap.

__________________________________________________________________________
Actividad en clase:

Los datos cats en la librería MASS presentan los pesos corporales y del cerebro de 144 gatos.
Realice bootstrap con estos datos para obtener información acerca de: (a) la Media y (b) la
Varianza. Interprete sus resultados.
___________________________________________________________________________
164

____________________________________________________________________________________

UNIDAD 6
______________________________________________________________________________________
________________________________________________________________

Generación de aplicaciones web interactivas con Shiny


Referencias web:
 Página principal: http://shiny.rstudio.com/
 Motivación: http://shiny.rstudio.com/gallery/
 Videos tutoriales: https://www.youtube.com/watch?v=Gyrfsrd4zK0
https://www.youtube.com/watch?v=UwwQrEcXtfc

6. 1 Introducción

Shiny es un paquete de R que hace que sea fácil crear aplicaciones web interactivas (apps)
directamente desde R o RStudio. No requiere de conocimientos previos de Java, y para crear
nuevos apps se requiere de conocer un poco del lenguaje R y algo de Html.

Para quienes les gustaría enseñan estadística de una manera dinámica o a investigadores a
quienes les gusta observar comportamientos de un conjunto de datos a medida que se le
cambie ciertos parámetros como el tamaño de muestra, este paquete es una excelente opción.

Para dar inicio a este proceso, primero debemos hacer la instalación del paquete “shiny” ya
sea desde el R básico o RStudio.

install.packages("shiny")

library(shiny)

runExample("01_hello") # Existen 11 ejemplo que muestran la versatilidad de este paquete

Seguir link: http://shiny.rstudio.com/tutorial/lesson1/


165

6.2 Estructura de un Shiny Apps


Shiny Apps tiene dos archivos los cuales deben estar contenidos en mismo directorio con el nombre
de la aplicación:

 Un editor de interface de usuario. Abreviado así: (ui.R).


 Un editor de servidor. Abreviado así: (server.R)

El editor de interfaz de usuario controla el diseño y el aspecto de la aplicación. Se define en una


secuencia de comandos de origen denominado ui.R. Veamos un ejemplo:
166

El editor de servidor contiene las instrucciones que el equipo necesita para construir su aplicación. Se
define en una secuencia de comandos de origen denominado server.R. Continuación del ejemplo
anterior:

Componentes generales de la estructura Shiny Apps: http://shiny.rstudio.com/images/shiny-


cheatsheet.pdf

6.3 Para corre mis Shiny Apps


Dentro de la consola de RStudio se escribe lo siguiente:

Nota: Se requiere tener la carpeta SHINY en el escritorio.

Veamos un ejemplo:

library(shiny)
setwd("C:\\Users\\user\\Desktop\\SHINY\\Mis Apps\\App1")
runApp()

También podría gustarte