Documentos de Académico
Documentos de Profesional
Documentos de Cultura
!
"!
1
e-mail: estevez@uninorte.edu.co
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
UNIDAD 2 ............................................................................................................................................. 71
PROGRAMACIÓN DE GRÁFICOS CON R ........................................................................................ 71
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
Programming in R - http://zoonek2.free.fr/UNIX/48_R/02.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.1. ¿Qué es R?
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: GPL
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
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
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:
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
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 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 )
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.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.
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?
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
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")
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. Escribiendo en el prompt:
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.
Seleccionamos como ventana del CRAN (The Comprehensive R Archive Network) a Colombia
(Bogotá):
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)
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))
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.
1.3. LA MATEMÁTICAS EN R
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
Tomado del libro: The R Book. Michael Crawley. Pag. 17. Ver libro electrónico.
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
8980206%%2
## [1] 0
redondeo(8.53)
## [1] 9
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.
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.
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
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=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
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
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"
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)
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
## 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
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
(b) extraer los valores de las posiciones pares, del vector anterior “num”.
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”).
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
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
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
## [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(x)
## [1] 6.083333
STOP Supongamos que un estudiante está muy desesperado y no encuentra el error que
–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
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.
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?
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)
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
Existen diferentes formas de crear o generar una matriz. Podemos crear uno directamente
utilizando la función matrix de la siguiente manera:
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
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
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]
## [1,] 1 2
## [2,] 3 4
## [3,] 4 3
## [4,] 2 1
36
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
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
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
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
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
C=A+B
C
## [,1] [,2]
## [1,] 3 10
## [2,] 8 17
C=A-B
C
## [,1] [,2]
## [1,] 1 4
## [2,] 4 1
C=A%*%B
C
## [,1] [,2]
## [1,] 16 62
## [2,] 24 90
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
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
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
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:
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
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
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
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] 0 0 0 0
44
𝜒2 = 𝑛(𝑥̅ − 𝜇 )´Σ−1(𝑥̅ − 𝜇 ) ≥ 𝜒2
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
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
lombrices=read.table("C:\\Users\\user\\Desktop\\worms.txt",header=T)
lombrices
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)
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)
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].
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,]
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
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
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),]
¿Qué hace R si quisiéramos ordenar más de una variable al mismo tiempo, por ejemplo
escojamos “Vegetation” y “Worm.density”?
51
lombrices[order(Vegetation,Worm.density),]
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,]
lombrices[sapply(lombrices,is.numeric)]
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
¿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"),]
faltante=read.table("C:/Users/user/Desktop/worms.missing.txt",header=T)
faltante
nuevo=na.omit(faltante)
nuevo
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
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
## 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
lombrices$Vegetation
unique(lombrices$Vegetation)
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
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.
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
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
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:
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
Enlace:
https://drive.google.com/drive/folders/0B3dFK0R9NddVcFo4T3k4UGM1aDA
61
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.
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:
Actividades en clase:
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.
== (igual)
!= (diferente)
>= (mayor o igual que)
<= (menor o igual que)
& (y)
| (o)
! (no o negación)
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
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.
if (condicional.lógico) {
comandos cuando VERDADERO
} else {
Comandos cuando FALSO
}
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.
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
fun.if= function(x) {
if(x>2) {
y=2*x
} else {
y=3*x
}
print(y)
}
fun.if
fun.if(4)
fun.if(-1)
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
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.
Sintaxis
Sintaxis
Sintaxis
repeat { comandos }
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.
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.
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){
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:
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
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
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.
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:
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
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( )”.
#Texto 1
#Texto 2
text(0,0.6,expression(L[t]==L[infinity](1-e^-k(t-t[0]))))
#Texto 3
#Texto 4
text(0,0,expression("r"==paste(frac(paste(mu[max]*"S"), paste("K"[s]+"S")))))
#Texto 5
#Texto 6
#Texto 7
Salida en R:
2. 3. GRÁFICOS BÁSICOS
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
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
También se le puede hacer una serie de ajustes en el tipo de letra, como se verá a continuación:
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")
legend(locator(1),c("setosa","virginica","versicolor"),pch=c(19,19,19),col=c("blue","green","red"))
81
attach(Datos)
#Cálculo de la regresión
regre = lm(Dorsal~Longitud)
modelo = summary(regre)
modelo
library(gplots)
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)
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)
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
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.
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.
datos2 = datos[,c("Familia","M2","M3","M4","M5")]
datos2M = aggregate(datos2[,c("M2","M3","M4","M5")],by=list(datos2$Familia),mean)
datos2M = datos2M[,-1]
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.
attach(datos)
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)
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)
attach(Datos)
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
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).
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")
legend("topleft",c("setosa","virginica","versicolor"),bty="n",
pch=c(19,19,19),col=c("blue","green","red"))
90
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
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.
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
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)
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")
plot.default(Mes,Temp,ylim=c(0,30),ann=FALSE,yaxt="n",type="l",lty=1, yaxs="i")
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)
#Primer histograma
par(new=T, omd=c(0,0.6,0.55,1))
lines(density(Dorsal,na.rm=TRUE),lwd=2,col="red")
#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),
lines(density(Longitud,na.rm=TRUE),lwd=2,col="red")
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),
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)
Y finalmente:
102
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.
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.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")
plot(G)
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)
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)
plot(T)
106
library(googleVis)
#Gráfico
plot(GT)
107
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.
library(plotrix)
#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)
library(plotrix)
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)
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
library(plotrix)
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
Modelo # 1:
library(lattice)
#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)
Modelo # 3:
Nota: Para correr este gráfico es necesario tener instalados los paquetes “MASS”, “ellipse” y
SciViews”
library(SciViews)
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)
Modelo #2:
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)
_______________________________________________________________________________________
UNIDAD 3
SIMULACIONES EN R
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)
x=rnorm(20, 30, 3) ; x
summary(x)
x=rpois(20, 5 ) ; x
a) Pr(x <= 8)
ppois(8, 5 )
ppois(13, 5 )
116
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")
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
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.
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
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:
sample(1:6, 1)
Si queremos simular la distribución de la suma de los números que salen al tirar 4 dados
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))
})
table(t)
barplot(table(t))
Ahora, Se podría haber procedido similarmente así:
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).
})
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.
Lo anterior solo fue, para unos pocos, pero si ahora generamos 10000 números aleatorios
entonces:
set.seed(111)
table(t)
barplot(table(t))
set.seed(111)
t = rnorm(100, 3, 2)
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.
d) Calcular el número máximo de accidentes que se producirán con probabilidad mayor o igual a 0.9.
Recordemos su sintaxis:
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:
𝑛
𝑃(𝑥) = ( ) 𝑝 𝑥 (1 − 𝑝)𝑛−𝑥
𝑥
Y se denota como X ~ Bin(n,p)
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.
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.
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:
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]
}
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
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)
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)
4. Una versión del teorema del límite Central dice que si X es una variable
aleatoria Poisson con parámetro λ, y
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
_____________________________________________________________________________
___________________________________________________________________
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
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.
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%.
√ √
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.
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))
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”.
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
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
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.
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.
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.
e. Ahora, verifique nuevamente la correlación entre las variables peso – altura pero
ahora para cada sexo. Interprete los resultados.
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.
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:
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:
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.
Instrucciones en Rcmdr:
Instrucciones en Rcmdr:
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:
Actividades de práctica:
1. Repita nuevamente todos los análisis anteriores pero ahora para el grupo de las mujeres.
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:
H0: µ = 175
H1: µ ≠ 175
H0: µ ≥ 175
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
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:
Solución
Instrucciones en Rcmdr:
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:
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.
Tipo de Aficiòn
Gènero Aficionado No aficionado
Hombre 150 97
Mujer 123 112
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:
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
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.
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
Fuente bibliográfica: Introductory Statistics with R Second edition, by Peter Dalgaard pag. 229.
Solución:
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:
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:
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
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
_______________________________________________________________
______________________________________________________________________________________
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.
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:
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".
Fuente: http://www.scalaformachinelearning.com/2016/05/bootstrapping-by-resampling-with.html
148
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.
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
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.
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)
# [ 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)
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:
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
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)
}
## [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")
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:
ˆ *
i
Eboot ˆ* i 1
1 B ˆ*
2
SEboot ˆ*
B 1 i 1
i Eboot ˆ*
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
#Media Observada:
mean(chem)
## [1] 4.280417
#Media Bootstrap:
mean(med)
## [1] 4.30943
## [1] 1.081326
## [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.
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))
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
## [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
Intervalos t
(̂ ) ( )
Intervalos de Percentiles
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:
(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.
## 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 )
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.
library(MASS)
data(galaxies)
##
## 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
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
______________________________________________________________________________________
________________________________________________________________
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)
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:
Veamos un ejemplo:
library(shiny)
setwd("C:\\Users\\user\\Desktop\\SHINY\\Mis Apps\\App1")
runApp()