curso intro duc to rio de r

67
Curso introductorio de R: Por Raúl Vaquerizo Romero . Capítulo 1: Descarga, instalación y primeras sentencias. Capítulo 2: Funciones gráficas básicas. Capítulo 3: Medidas de estadística descriptiva. Capítulo 4: Trabajo con datos I. Capítulo 5: Inferencia estadística. Ejemplos . Capítulo 6: Primeros ejemplos prácticos. Capítulo 7: Regresión lineal con R. Capítulo 8: Más ejemplos de regresión lineal. Capítulo 9: Análisis de Componentes Principales. Capítulo 10: Análisis de conglomerados (cluster) I. Capítulo 11: Análisis de conglomerados (cluster) II. Capítulo 12: Introducción al análisis de la varianza.

Upload: joao-paulo-motta

Post on 24-Jun-2015

176 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Curso Intro Duc to Rio de R

Curso introductorio de R:Por Raúl Vaquerizo Romero.

Capítulo 1:     Descarga, instalación y primeras sentencias.

Capítulo 2:      Funciones gráficas básicas.

Capítulo 3:       Medidas de estadística descriptiva.

Capítulo 4:       Trabajo con datos I.

Capítulo 5:       Inferencia estadística. Ejemplos .

Capítulo 6:       Primeros ejemplos prácticos.

Capítulo 7:       Regresión lineal con R.

Capítulo 8:       Más ejemplos de regresión lineal.

Capítulo 9:       Análisis de Componentes Principales.

Capítulo 10:   Análisis de conglomerados (cluster) I.

Capítulo 11: Análisis de conglomerados (cluster) II.

Capítulo 12: Introducción al análisis de la varianza.

Page 2: Curso Intro Duc to Rio de R

Capítulo 1: Descarga, instalación y primeras sentencias.

 

Bien, como lo prometido es deuda a partir del día de hoy estoy manos a la obra para prepararos un pequeño manual de R. Espero que os lo halláis descargado si no haced clic aquí y comenzareis a formar parte de la comunidad de R; la parte del módulo base para empezar os la podéis descargar en en este sitio. Tenéis el módulo base y las contribuciones. R es un programa con código totalmente libre, se puede contribuir a su mejora ofreciendo nuevos paquetes que los programadores cuelgan en Internet, de momento no vamos a analizar los paquetes y las contribuciones personales a R pero es este el aspecto más importante de esta aplicación, R es totalmente libre y podemos programar nuestros análisis y tareas más comunes de una forma sencilla y práctica esto hace de R la herramienta para la estadística más barata y asequible sin olvidarnos que las contribuciones personales hacen de R cada vez más completo y potente.

En la página web http://www.r-project.org/ tenéis un estupendo manual más completo y más bonito, pero el mío va directamente al grano y no entra en todas las exquisiteces que tiene este excelente programa. 

¡Fuera introducciones! Comenzamos a manejar datos para ello sólo es necesario tener el módulo base que ya os habéis instalado en vuestra máquina: 

Con R creamos objetos, hasta aquí todo muy bien nadie se pierde y los creamos del siguiente modo: 

> felipe<-1 Creamos el objeto felipe > felipe Le llamamos[1] 1 R nos lo ofrece> objects() Listamos objetos sin parámetros no entro en las posibilidades por

no liarme[1] "felipe" Solo tenemos un objeto que es felipe

 La forma que tiene R de almacenar los datos se basa en esta creación de objetos y a partir de ella creamos nuestros conjuntos de datos en función de nuestras necesidades. Los conjuntos de datos que yo suelo emplear son vectores (vector) y matrices (matrix). Más adelante funcionamiento del modo lista (list) y los data frame.

 Un vector:

> felipe<-c(1,2,3,4)> felipe[1] 1 2 3 4

Sobra decir que R sobrescribe objetos ya creados. 

Una matriz:

2 6 4

Page 3: Curso Intro Duc to Rio de R

5 8 90 2 0> datos<-matrix(c(2,5,0,6,8,2,4,9,0),ncol=3)> datos [,1] [,2] [,3][1,] 2 6 4[2,] 5 8 9[3,] 0 2 0

Sólo podemos manejarnos con datos numéricos. Si queremos nombrar las columnas tenemos que trabajar más la sentencia matrix:

> datos<-matrix(c(2,5,0,6,8,2,4,9,0),ncol=3,+ dimnames=list(c("Matematicas","Lengua","Ingles"),+ c("Juan","Lucia","Serafin")))> datos Juan Lucia SerafinMatematicas 2 6 4Lengua 5 8 9Ingles 0 2 0

Esta sentencia también puede servir para tomar contacto con la estructura de datos lista. Nos limitamos a poner nombre por fila y por columna mediante instrucciones, el símbolo + nos lo ofrece el sistema automáticamente cuanto pulsamos intro y significa que espera más instrucciones o parámetros. Si nos equivocamos al teclear las sentencias con las teclas cursor podemos retomar las sentencias anteriores y corregir los fallos además de acceder rápidamente a las instrucciones anteriores, R también acepta contar y pegar así que para ir practicando podéis cortar y pegar de esta página (a buenas horas os lo digo). 

También podéis leer de ficheros planos pero ahora mismo no tengo ningún ejemplo a mano... os indico como se hace:

> fichero <- read.table(“a:\\datos”) modo mas simple> fichero <- read.table(“a:\\datos”,header=T) si las variables o los datos contienen nombre o cabecera.

Capitulo 2: Funciones gráficas básicas.

El siguiente paso en el pequeño manual que sigo construyendo es el manejo de las funciones gráficas de bajo nivel, sin entrar en todas las posibilidades que tiene R (de nuevo comentar que en http://www.r-project.org/ tenéis un completísimo y aburrido manual) os voy a plantear algunos usos muy interesantes para posteriores aplicaciones donde quizá veamos más en profundidad alunos aspectos.

Gráficos de dispersión:

> x<-c(1,2,3)> y<-c(4,5,6)

Page 4: Curso Intro Duc to Rio de R

> plot(x,y)

Obtenemos el mas básico de todos los gráficos. Espero que lo vayais haciendo vosotros a l vez con vuestro R porque sólo pienso poneros los gráficos que merezca la pena reseñar. Continúo con la representación gráfica de funciones donde además podéis ver como actúan las sentencias function y seq, imaginemos que deseamos representar la función f(x,y)=x+3y:

>x<-seq(-10,10,lenght=20)> y<-seq(-10,10,lenght=20)> ejem<-function (x, y){x+3*y}> persp(x,y, outer(x,y, fun=ejem))

Podéis comprobar que os ofrece un estupendo gráfico en tres dimensiones donde une los puntos de x e y formando un plano. Por supuesto también existe la posibilidad de hacer funciones más complejas con cuadrados, cubos, etc... en R basta con poner el símbolo ^ para representar potencias. Ahora vamos a pasar a la parte de la estadística descriptiva para la representación de datos unidimensionales:

> piechart (datos) Diagrama de sectores

> hist (datos, nclass=n) Histograma con número de barras

> barplot (datos) Diagrama de barras

> boxplot(datos) Diagrama de cajas y bigotes

Por supuesto que estas funciones gráficas tienen muchas posibilidades más pero de momento estoy con una simple introducción, pero posteriormente me iré adentrando en las esquisiteces de estas funciones que son muchas. A continuación os expongo algunas de las opciones con las que podéis contar, para añadir estas opciones sólo tenéis que incluirlas a continuación del conjunto de datos; funcion_grafica(datos,opcion=parámetro)

(datos, main="titulo")Añadir título

(datos, xlab="etiqueta", ylab="etiqueta") Etiquetas en ejes

(datos,type="l") Realiza un gráfico de líneas.

(datos,col="nombre") Colores de los gráficos

(datos,breaks=numero) Intervalos

Las posibilidades que nos ofrece R son muy amplias y poco a poco las iremos viendo con mayor detenimiento aplicadas a ejemplos más concretos.

Capítulo 3: Medidas de estadística descriptiva.

Comenzamos a trabajar con medidas estadísticas, de momento pondré las medidas clásicas y posteriormente añadiré diversas funciones para que  podamos trabajar con

Page 5: Curso Intro Duc to Rio de R

métodos robustos, estas medidas robustas las tendremos que programar nosotros (en este caso yo) así que su fiabilidad puede dejar algo que desear pero si alguien se atreve a programar conmigo.. . De todas formas recomendaros el curso de la UNED de Experto Universitario en Estadística Aplicada. Aun así espero poner a vuestra disposición mis pequeños conocimientos sobre el tema y también explicaros como añadir módulos a vuestro programa R aunque de nuevo si vais a la página web del proyecto R y os entretenéis en leer un ratito no creo que os cueste mucho.

Pues bien, aquí tenéis las funciones estadísticas más comunes con R:

Medidas de dispersión

Frecuencias acumuladas

> cumsum(datos)

Media aritmética > mean (datos)

Mediana > median(datos)

Cuantiles

> cuantile(datos) #obtenemos los cinco cuantiles

> cuantile(datos,prob=p) #obtenemos un cuantil concreto

El símbolo # no tiene ninguna función estética, es la forma de poner comentarios mediante R. por otro lado si quisiéramos las medidas de posición más comunes emplearíamos el comando summary(datos) y tendríamos recogidos las medidas anteriores.

Medidas de dispersión

Cuasivarianza > var(datos)

Como medida de dispersión R nos ofrece la cuasivarianza, si queremos obtener la varianza o la desviación típica tenemos que transformar lo que podemos obtener con R a nuestro antojo. A partir de este momento vamos a programar nuestras propias funciones.

La varianza como me imagino que sabreis es [(n-1)/n]*cuasivarianza y la desviación típica es su raiz cuadrada; en R es del siguiente modo:

Varianza > ((length(datos)-1)/length(datos))*var(datos)

De nuevo tenemos nuevas funciones. La función length sirve para conocer el tamaño de un vector, para conocer el número de observaciones n. Pues si cada vez que queramos determinar la varianza tenemos que hacer esto lo llevamos claro. Soy un poco exagerado, tampoco hay que escribir tanto, pero es una ocasión estupenda para que podais empezar a programar en R:

> varianza<-function(x) { ((length(x)-1)/length(x))*var(x) }

Editamos la función varianza

Page 6: Curso Intro Duc to Rio de R

varianza(datos)Comprobamos su funcionamiento

Veamos más en profundidad como se editan funciones en R. Asignamos a un objeto varianza el valor de una función que recibe un único parámetro x esa función viene editada entre llaves { }. Para comprobar como funciona basta con ejecutarla como otra función cualquiera.

Ahora bien si queremos conservar la función editada al cerrar nuestra sesión de R nos aparecerá un mensaje qestion que nos pregunta si queremos guardar la imagen (Save workspace image?) nosotros decimos que si y la aplicación nos guarda todo lo que hemos hecho hasta el momento en la presente sesión de R. ¿Por qué no os lo comenté antes? Pues simplemente porque se me ha olvidado... Tendré que dedicarme en algún otro capítulo al manejo de archivos y a la lectura de datos, pero es que eso me aburre un montón.

Capitulo 4: Trabajo con datos I.

Como paso previo a la creación de conjuntos de datos cabe señalar que con R podemos importar datos tanto de otras aplicaciones como SAS, SPSS,... como de ficheros de texto planos. Digo esto porque nos sería muy complicado el crear un fichero de datos más o menos grande con las funciones de R que conocemos hasta la fecha ya que sería muy engorroso, además en la mayoría de las ocasiones que realicemos un estudio los datos serán  un fichero ASCII.

Por otra parte si queremos introducir los datos mediante R también podemos emplear la función scan(); creamos el vector vector.ej:

> vector.ej<-scan()1: 2.3 4.5 6.7 4: 3 .5 5.6 88: Read 7 items

Simplemente nos limitamos a ir introduciendo los datos, seguidamente pulsamos intro y en este caso R nos indica con 4: que ya llevamos 3 elementos y que el siguiente elemento es el cuarto, si pulsamos dos veces intro salimos de la función y R nos indica que ha leido 7 items. Es otra forma de introducir los datos un poco más cómoda que la que habíamos visto hasta ahora pero que sigue teniendo sus limitaciones como por ejemplo que no podemos trabajar con variables alfanuméricas. Esta función scan puede contener como argumentos el fichero   ASCII  del cual provienen los datos:

Conjunto de datos datos.txt:  

2.3 4.5 6.7 3.5 5.6 8

> vector.ej<-scan(c:\\ruta completa\\datos.txt)

Page 7: Curso Intro Duc to Rio de R

Deciros que no me he equivocado y que en la ruta hay que poner \\ en vez de \. Esta es la forma que tiene R de leer los datos. Pero de nuevo tiene sus limitaciones ya que para leer datos de esta forma el fichero plano tiene que tener una estructura de lo más básica. Si por ejemplo la estructura fuera del tipo:

Nombre Apellidos Salario EdadFernando Torres 12000 45Arturo Fernandez 30000 56Felipe Miñambres 24000 34David Tejero 10000 23

Se puede ver que la primera fila contiene los nombres de las variables, la función R apropiada para estos casos es read.table que tiene una estructura muy sencilla:

> empresas <- read.table("C:\empresa.dat",header=TRUE)Warning message: incomplete final line found by readTableHeader on `C:empresa.dat' > empresas Nombre Apellidos Salario Edad1 Fernando Torres 12000 452 Arturo Fernandez 30000 563 Felipe Miñambres 24000 344 David Tejero 10000 23

Obtenemos un mensaje de error que no debe preocuparnos (espero) ya que el conjunto de datos empresas aparece completo como deseábamos. Con esta función hemos creado una estructura de datos (que ya referenciábamos en el primer capítulo del manual) llamada data frame que puede leer objetos de varios tipos por columnas. Posteriormente con estos objetos podemos realizar los pertinentes estudios. Otra nota a añadir es que R nos indexa las observaciones si no le indicamos una columna índice esto se realiza con al función row.names=1.

A partir de este momento estamos en disposición de empezar a trabajar más en profundidad con R, estamos en disposición de realizar estudios estadísticos y contrastes de muchos y variados tipos y  posteriormente importar datos de otras aplicaciones y realizar análisis muy completos con una herramienta gratuita y de fácil manejo. Si no tienes SAS en casa tranquilo que puedes defenderte estupendamente con R.

Capitulo 5: Inferencia estadística.

En este capítulo voy a hacer memoria  y recordar algunos términos y conceptos básicos  de estadística. En  primer lugar hacemos  inferencia a partir  de unas observaciones obtenidas a partir de  la población a las que vamos a extraer  unas propiedades que se denominan estadísticos muestrales. Además vamos a conocer la distribución de dichos  estadísticos  (generalmente distribución normal) por lo que hacemos  inferencia paramétrica.

La inferencia paramétrica puede recogerse en una vertiente o en otra  según el parámetro a estimar; tenemos por un lado la estadística clásica (que es en la que nos vamos a centrar) y por otro lado la estadística  ballesiana.

Page 8: Curso Intro Duc to Rio de R

La estadística paramétrica clásica plantea tres tipos de problemas:

Estimación puntual en la que pretendemos dar un valor al parámetro a estimar. Estimación por intervalos (buscamos un intervalo de confianza)

Contrastes de hipótesis donde buscamos contrastar información acerca del parámetro.

Tenemos un experimento, lo repetimos varias veces y obtenemos una muestra con variables aleatorias independientes idénticamente distribuidas con función de distribución conocida. (Por ejemplo tenemos las alturas de 30 varones españoles y estimo que la altura media de los españoles es 1,77 estamos ante una estimación puntual). Pues cualquier función de la muestra que no dependa del parámetro a estimar es un estadístico y aquel estadístico que se utiliza para inferir sobre el parámetro desconocido es un estimador. Ejemplos de estadísticos son el total muestral, la media muestral, la varianza muestral, la cuasivarianza muestral, los estadísticos de orden,...

Conocemos los conceptos básicos  para comenzar a trabajar, también sabemos que las observaciones del experimento generalmente tienen distribución normal (esto es inferencia paramétrica). Ahora bien, necesitamos determinar unas distribuciones en el muestreo que estén asociadas con la distribución normal. Estas distribuciones son la chi-cuadrado, la t de Student y  la F de Snedecor.

"La chi-cuadrado es una suma de normales al cuadrado" más o menos se podía definir así ya que si calculamos la distribución de una variable normal al cuadrado no podemos aplicar cambio de variable y a partir de su función de distribución  llegamos a una función de densidad de una gamma con parámetros 1/2 y 1/2 que es una chi-cuadrado con 1 grado de libertad. La gamma es reproductiva respecto al primer parámetro por lo que sumas de normales (0,1) nos proporcionan gammas de parámetros n/2 y 1/2 o lo que es lo mismo chi-cuadrado con n grados de libertad.

La t de Student se crea a partir de una normal (0,1) y una chi-cuadrado con n grados de libertad independientes. Una variable se distribuye bajo una t de Student si se puede definir como normal(0,1) dividido por la raíz cuadrada de una chi-cuadrado partida por sus grados de libertad; difícil de comprender así mejor veamos un ejemplo:

Z1, Z2 ,Z3 ,Z4 variables aleatorias independientes idénticamente distribuidas bajo una N(0,1)Z1 / [(Z2+Z3+Z4)/3]^1/2 esto se distribuye según una t de Student de 3 grados de libertad

La F de Snedecor se crea a partir de dos chi-cuadrado independientes dividivas por sus respectivos grados de libertad, así la F de Snedecor tiene dos parámetros que indican sus grados de libertad:

X se distribuye como chi-cuadrado

con m grados de libertad

==> F=(X/m)/(Y/m) es F de snedecor con m,n grados de libertad

Page 9: Curso Intro Duc to Rio de R

Y se distribuye como chi-cuadrado

con n grados de libertad

Me dejo en el tintero muchos aspectos como las distribuciones de los estadísticos o los métodos de construcción de contrastes e intervalos pero me podría extender mucho, y me extenderé pero hasta aquí os cuento de momento. Aun así recomendaros una bibliografía básica por si queréis profundizar más en el tema. También estoy a expensas de poder publicar archivos LaTeX para que los aspectos matemáticos queden mejor resueltos pero de momento conformaros con los ejemplos de más abajo.

Bueno pues comencemos con R, la función que nos ofrece tanto estimaciones puntuales como intervalos de confianza como contrastes de hipótesis es:

> t.test (datos_x, datos_y =NULL, alternative = "two.sided", mu = 0,

paired =FALSE, var.equal = FALSE, conf.level= 0.95)

Las opciones indicadas son todas las ofrecidas por defecto. Podemos poner sólo un conjunto de datos para muestras unidimensionales (estimaciones puntuales) los dos conjuntos para comparación de muestras. 

El argumento alternative indica el tipo de contraste, bilateral two.sided, si la hipótesis alternativa es mayor (Ho: menor o igual) se utiliza greater, si la hipótesis alternativa es menor (Ho: mayor o igual) entonces se usa less.

En mu indicamos el valor de la hipótesis nula.

En paired=T estamos ante una situación de datos  no apareados para indicar que estamos ante datos apareados poner paired=F.

Con var.equal estamos estamos trabajando con los casos de igualdad o no de varianzas que sólo se emplean en comparación de dos poblaciones. Si var.equal=T las varianzas de las dos poblaciones son iguales si var.equal=F las varianzas de ambas poblaciones no se suponen iguales. 

Por último tenemos el argumento conf.level en el que indicamos el el nivel de confianza del test. 

Si deseáramos hacer el contraste para la igualdad de varianzas (cociente de varianzas=1) habríamos de emplear la función var.test:

var.test(x, y, ratio = 1, alternative = c("two.sided", "less", "greater"),

conf.level = 0.95, ...)

Los argumentos son los mismos que en la función t.test.

Ejemplo 5.1: 

Page 10: Curso Intro Duc to Rio de R

Con objeto de estimar la altura de los varones españoles menores de 25 años se recogió una muestra aleatoria simple de 15 individuos que cumplían ese requisito. Suponiendo que la muestra se distribuye normalmente determinar un intervalo de confianza al 95% para la media. 

Tenemos una variable con distribución normal de media y desviación típica desconocidas por ello el intervalo de confianza ha de ser:

Veamos el programa R: 

> alturas<-scan()

1: 1.77 1.80 1.65 1.69 1.86 1.75 1.58

8: 1.79 1.76 1.81 1.91 1.78 1.80 1.69 1.81

16:

Read 15 items

> t.test(alturas) One Sample t-testdata: alturas

t = 82.3296, df = 14, p-value = < 2.2e-16

alternative hypothesis: true mean is not equal to 0

95 percent confidence interval:

1.717396 1.809270

sample estimates:

mean of x

1.763333

El intervalo es [1.71,1.80]. La función t.test no tiene ningún argumento opcional puesto que los necesarios son los que recoge por defecto. Ahora imaginemos que lo que queremos es estimar si la altura media de los españoles es de 1.77 metros hay que introducir algunas modificaciones:

> t.test(alturas,mu=1.77) One Sample t-testdata: alturas

t = -0.3113, df = 14, p-value = 0.7602

alternative hypothesis: true mean is not equal to 1.77

95 percent confidence interval:

Page 11: Curso Intro Duc to Rio de R

1.717396 1.809270

sample estimates:

mean of x

1.763333

Como se puede ver p-value = 0.7602 indica que con un nivel de significación del 5% se acepta la hipótesis de que las altura media de los españoles es de 1.77 metros.

Ejemplo 5.2: 

El director de una sucursal de una compañía de seguros espera que dos de sus mejores agentes consigan formalizar por término medio el mismo número de pólizas mensuales. Los datos de la tabla adjunta indican las pólizas formalizadas en los últimos cinco meses por ambos agentes.

Agente A Agente B

12 14

11 18

18 18

16 17

13 16

Admitiendo que el número de pólizas contratadas mensualmente por los dos trabajadores son variables aleatorias independientes y distribuidas normalmente: ¿Tiene igual varianza?  ¿Se puede aceptar la hipótesis del director de la sucursal en función de los resultados de la tabla y a un nivel de confianza del 99%?

Primero comprobamos si los datos tienen igual varianza:

> agente_A<-c(12,11,18,16,13)

> agente_B<-c(14,18,18,17,16)

> var.test(agente_A,agente_B) F test to compare two variancesdata: agente <- A and agente <- B

F = 3.0357, num df = 4, denom df = 4, p-value = 0.3075

alternative hypothesis: true ratio of variances is not equal to 1

Page 12: Curso Intro Duc to Rio de R

95 percent confidence interval:

0.3160711 29.1566086

sample estimates:

ratio of variances

3.035714

Los datos recogidos tienen igual varianza ya que no se rechaza la hipótesis de igualdad de varianzas. Como los datos están distribuidos normalmente y las varianzas son iguales los agentes harán la misma cantidad de pólizas si la diferencia de sus medias es estadísticamente distinta de 0, esta es la hipótesis de partida. Esta hipótesis de rechaza cuando:

> t.test (agente_A,agente_B, paired=T, conf.level=0.99) Paired t-testdata: agente <- A and agente <- B

t = -2.1518, df = 4, p-value = 0.09779

alternative hypothesis: true difference in means is not equal to 0

99 percent confidence interval:

-8.163151 2.963151

sample estimates:

mean of the differences

-2.6

Por poco pero se puede aceptar la hipótesis nula ya que el p-value = 0.09779 es superior al 0.01 que establecimos de partida.

Capitulo 6:Primeros ejemplos prácticos.

Bueno hasta ahora he tratado de mostraros algunas funciones de R para que empezarais a tomar contacto con la herramienta, no he trabajado con ningún ejemplo concreto a excepción del  capítulo 5 donde os presenté la función t.test y sus argumentos con algún caso aplicado. Pues bien, en este capítulo voy a trabajar con ejemplos de todo lo que hemos visto hasta ahora para que sirva además de leve repaso.

Page 13: Curso Intro Duc to Rio de R

Mi página existe desde finales de junio de 2002 y siempre he querido saber cual ha sido el número medio de visitas, geocities me ofrece estadísticas desde finales de julio así que voy a tomar como referencia el mes de agosto. La media de  visitas a la página en el mes de agosto fueron:

> visitas<-scan()1: 27 27 13 9 21 42 26 20 28 23 10 34 19 19 15 13 918: 10 17 22 17 9 21 4 9 20 20 31 21 30: 16 1632: Read 31 items> mean(visitas)[1] 18.96774

¡Sólo 19 visitas diarias a mi página! con lo que me la estoy currando, a ver si venís más de vez en cuando sólo para que vaya bien el contador. El caso es que tiene altos y bajos, vamos a verlo en un gráfico:

> plot (visitas,type="l",main="Que poco me visitais")

 

Como vemos R conserva el orden ya que en el eje de ordenadas aparece index, para que la función plot una por líneas le añadimos type="l" y con main indicamos el título. Los gráficos no tienen una resolución gráfica excelente y además el trabajar con ellos es un

Page 14: Curso Intro Duc to Rio de R

poco engorroso pero son más que suficientes para presentar un informe escrito con cualquier editor de texto ya que basta con cortar y copiar.

Si quiero hacer un gráfico de sectores por las visitas por semana:

> semanas<-scan()1: 31 31 31 315: 32 32 32 32 32 32 3212: 33 33 33 33 33 33 33 19: 34 34 34 34 34 34 3426: 35 35 35 35 35 3532: Read 31 items> pie(visitas,col=semanas)

Se puede añadir leyenda con la función legend pero eso espero lo guardo para un capítulo posterior donde veremos otras funciones, como cambiar colores, ver varios gráficos en una sola ventana,...

Si quisiéramos hallar la varianza habríamos de crearnos la función ya que R calcula la cuasivarianza muestral, esto ya lo vimos en el capítulo 3. De todas formas el programa sería:

> varianza<-function(x) { ((length(x)-1)/length(x))*var(x) }> varianza(visitas)[1] 67.64412> sqrt(varianza(visitas))[1] 8.224605

Imaginemos ahora que tenemos un fichero ASCII que recoge llamadas a un número de ayuda. Queremos saber si el número de llamadas de los usuarios difiere según los turnos, las semanas o los días.

Page 15: Curso Intro Duc to Rio de R

> llamadas<-read.table ("c:\datos\\calls.dat")

> llamadas V1 V2 V3 V41 1 1 Mon 92 1 2 Mon 16...164 11 2 Fri 41165 11 3 Fri 53

R indexa si no le indicamos lo contrario, además nombra las variables como V1, V2, V3 y V4. Si queremos nombrar las variables debemos emplear la función names.

> names(llamadas)<-c("Semanas", "Turno", "Dia", "Llamadas")

Es conveniente hacer un sumario para que podáis ver los valores que toman las variables que componen el conjunto de datos:

> summary(llamadas) Semanas Turno Dia Llamadas Min. : 1 Min. :1 Fri:33 Min. : 8.0 1st Qu.: 3 1st Qu.:1 Mon:33 1st Qu.: 67.0 Median : 6 Median :2 Thu:33 Median :129.0 Mean : 6 Mean :2 Tue:33 Mean :113.5 3rd Qu.: 9 3rd Qu.:3 Wed:33 3rd Qu.:153.0 Max. :11 Max. :3 Max. :550.0

También puede interesarnos sólo el saber el número medio de llamadas, para ello tenemos que acceder a la variable de un data frame, esto se hace con el símbolo $ después del nombre del objeto data frame:

> mean(llamadas$Llamadas)[1] 113.4545

Capitulo 7: Regresión Lineal.

En este capítulo vamos a ver como realiza el análisis de regresión R. Los modelos de regresión lineal son modelos probabilísticos basados en una función lineal, expresamos una variable en función otro conjunto de variables. Los pasos básicos a seguir en el estudio de un modelo lineal son:

1. Escribir el modelo matemático con todas sus hipótesis. 2. Estimación de los parámetros del modelo.

3. Inferencias sobre los parámetros.

4. Diagnóstico del modelo.

Page 16: Curso Intro Duc to Rio de R

No nos vamos a detener en todos los pasos puesto que si lo hiciéramos el capítulo quedaría demasiado extenso. Vamos a analizar las posibilidades que tenemos con R y para que nos pueden servir los modelos lineales.

La función que realiza los modelos lineales en R es lm "lineal model". Pero esta función no nos ofrece ninguna salida por pantalla si no que nos crea un objeto, o mejor dicho, nosotros creamos un objeto que va a ser un modelo de regresión lineal. Este objeto puede ser referenciado por cualquier función para realizar un análisis de la varianza, un modelo autoregresivo,... La función lm tiene la siguiente sintaxis:

lm(formula, data, subset, weights, method = "qr", model = TRUE, x = FALSE, y = FALSE, qr = TRUE, contrasts = NULL, ...)

En formula ponemos el modelo expresado: y ~ x1+x2+...+xn

En data especificamos el data frame que contiene las variables del modelo en el caso de que trabajemos con un data frame.

En subset especificamos un subconjunto de observaciones para validar posteriormente el modelo.

En weights especificamos los pesos, útil si hacemos mínimos cuadrados ponderados.

Con method especificamos el método. No entramos puesto que con el módulo base sólo es posible obtener el modelo por mínimos cuadrados.

En model con TRUE decimos a R que ha de guardarse en el objeto, la matriz del modelo, la frame,...

En contrast podemos especificar objetos con los que realizar contrastes sobre los parámetros.

Tiene múltiples opciones, para ver cuales son podéis poner en la línea de comandos ?lm y accederéis a la ayuda de R sobre el procedimiento lm. En este caso para conocer mejor su funcionamiento vamos a ver ejemplos ya que es la forma más apropiada de ir aprendiendo:

Ejemplo 7.1:

El timepo que tarda un sistema informático en red en ejecutar una instrucción depende del número de usuarios conectados a él. Si no hay usuarios el tiempo es 0. Tenemos los siguientes datos:

Nº usuarios Tiempo de ejecución

10 1

15 1.2

20 2

20 2.1

Page 17: Curso Intro Duc to Rio de R

25 2.2

30 2

30 1.9

Se pretende ajustar un modelo lineal sin término independiente, construir la tabla ANOVA y comparar el modelo con el de término independiente. Comencemos:

> tiempo<-c(1,1.2,2,2.1,2.2,2,1.9)> usuarios<-c(10,15,20,20,25,30,30)> ejemplo7.1<-lm(tiempo~usuarios-1) #se crea un objeto con el modelo lineal> summary(ejemplo7.1) #sumarizamos el objeto para ver el modeloCall:lm(formula = tiempo ~ usuarios - 1)Residuals: Min 1Q Median 3Q Max -0.4831 -0.1873 0.2056 0.3127 0.5113 Coefficients: Estimate Std. Error t value Pr(>|t|) usuarios 0.079437 0.006496 12.23 1.82e-05 ***---Signif. codes: 0 `***' 0.001 `**' 0.01 `*' 0.05 `.' 0.1 ` ' 1 Residual standard error: 0.3871 on 6 degrees of freedomMultiple R-Squared: 0.9614, Adjusted R-squared: 0.955 F-statistic: 149.5 on 1 and 6 DF, p-value: 1.821e-05

Los modelos se escriben de la forma dependiente~indepentiente1+independiente2+...+independienten con -1 le indicamos a R que es un modelo sin término independiente. En este caso el modelo resultante sería:  tiempo de ejecución=0.0794usuarios, también decir que es un excelente modelo lineal ya  que el Multiple R-Squared: 0.9614  (coeficiente de determinación ajustado) es bastante próximo a 1 (el mejor valor posible). Para construir la tabla del análisis de la varianza hemos de emplear la instrucción anova(objeto). El objeto lógicamente va a ser nuestro modelo lineal:

> anova(ejemplo7.1)Analysis of Variance TableResponse: tiempo Df Sum Sq Mean Sq F value Pr(>F) usuarios 1 22.4011 22.4011 149.53 1.821e-05 ***Residuals 6 0.8989 0.1498 ---Signif. codes: 0 `***' 0.001 `**' 0.01 `*' 0.05 `.' 0.1 ` ' 1

Ejemplo 7.2:

Nos han enviado por correo electrónico un archivo de texto que contiene las notas de la asignatura de estadística de un centro universitario. Nos piden que hagamos un modelo para predecir las notas finales a partir de las notas de los exámenes previos, el test y la puntuación del laboratorio. Pincha aquí para ver el archivo. La descripción del archivo viene recogida en la siguiente tabla:

Variable Tipo Column Descripción añadida

Page 18: Curso Intro Duc to Rio de R

as

ID del estudiante alfanumérico 1-3  

genero alfanumérico 5 f=emenino m=masculino

clase numérico 7 2=alevín 3=junior 4=senior

puntuación de test numérico 9-10 puntos máximos = 50

puntuación del examen 1 numérico 12-14 puntos máximos = 100

puntuación del examen 2 numérico 16-18 puntos máximos = 100

puntuación de laboratorio numérico 20-22 puntos máximos = 100

puntuación del examen final

numérico 25-27 puntos máximos = 200

Comencemos a trabajar con R:

> archivo<-read.table("c:\\datos\\GRADES.TXT") #leemos el archivo> nombres<-c("ID","sexo","clase","test","exam1","exam2","labo","final")> names(archivo)<-nombres #nombramos las variables> ejemplo7.2<-lm(final~test+exam1+exam2+labo,data=archivo) #hacemos el modelo> summary(ejemplo7.2) #sumarizamosCall:lm(formula = final ~ test + exam1 + exam2 + labo, data = archivo)Residuals: Min 1Q Median 3Q Max -75.5711 -10.5697 0.7903 15.8257 32.6372 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) -17.8277 50.2996 -0.354 0.72471 test 0.8606 0.7650 1.125 0.26672 exam1 0.6709 0.2413 2.781 0.00795 **exam2 0.4316 0.3667 1.177 0.24547 labo 0.2924 0.6182 0.473 0.63855 ---Signif. codes: 0 `***' 0.001 `**' 0.01 `*' 0.05 `.' 0.1 ` ' 1 Residual standard error: 21.06 on 44 degrees of freedomMultiple R-Squared: 0.4716, Adjusted R-squared: 0.4236 F-statistic: 9.818 on 4 and 44 DF, p-value: 9.142e-06

He aquí el modelo resultante del que como podemos ver sólo nos quedaríamos con la variable exam1 ya que los contrastes para las restantes estimaciones de parámetros no se rechaza la hipótesis de partida de nulidad del parámetro. Quizá estemos ante un problema de multicolinealidad ya que habrá una alta dependencia lineal entre las variables regresoras. Para ver la dependencia lineal hemos de ver el coeficiente de correlación, la forma en que se haya la matriz de correlaciones es la siguiente:

> co1<-cor(archivo$test,archivo$exam1)> co2<-cor(archivo$test,archivo$exam2)

Page 19: Curso Intro Duc to Rio de R

> co3<-cor(archivo$test,archivo$labo)> co4<-cor(archivo$exam1,archivo$exam2)> co5<-cor(archivo$exam1,archivo$labo)> co6<-cor(archivo$exam2,archivo$labo)

 La forma no es muy ortodoxa, pero no se me ocurre otra forma mejor de hacerlo, como vemos creamos objetos que contienen los coeficientes de correlación se crean con la función cor. Los listamos y construimos la matriz de correlaciones con nuestros medios o con la función matix. Yo lo hago manualmente y la matriz queda:

  test exam1 exam2 labo

test   0.53 0.48 0.60

exam1     0.52 0.033

exam2       0.23

labo        

No están todas altamente correladas, debe de existir alguna combinación lineal de algunas de ellas pero a simple vista no se detecta. Habríamos de buscar un modo de ver como se "infla" la varianza si quitamos alguna variable regresora. De momento no sé el modo de hacerlo con R pero espero poder solventarlo pronto. También desconozco como seleccionar el modelo de regresión más adecuado. En cuanto al análisis de residuos me lo reservo para un posterior capítulo porque sería interesante conocer algunas posibilidades gráficas que tiene R.

Capitulo 8: Más ejemplos de Regresión Lineal.

En este capítulo nos vamos a centrar en ver más ejemplos de regresión y en ver las posibilidades gráficas que tiene R al respecto, las posibilidades que son todas las que se quieran ya que como hemos visto en capítulos anteriores es muy fácil programar tus própios análisis estadísticos. Digo esto por si alguien no está acostumbrado a seguir una metodología distinta a la hora de realizar los modelos. Además el programar tus propios métodos hace que puedas comprender mejor las salidas por pantalla y los pasos que sigue el programa. En el primer ejemplo que vamos a ver partimos del ejemplo 7.2 del capítulo 7 que si recordamos era un modelo de regresión múltiple donde teníamos problemas de multicolinealidad.

Ejemplo 8.2:

Si recordamos en el ejemplo 7.2 nos pedían que hicieramos un modelo para predecir las notas finales a partir de las notas de los exámenes previos, el test y la puntuación del laboratorio. Teníamos una variable dependiente que era la nota final y cuatro variables regresoras. Vimos que el modelo presentaba múltiples lagunas (multicolinealidad, un modelo con un r cuadrado bajo,...). Pues ahora nos piden mejorar el modelo. Es difícil mejorarlo en precisión porque no tenemos más variables regresoras en el conjunto de datos por eso podemos mejorarlo haciéndolo más sencillo y recogiendo una cantidad de información lo más grande posible con un modelo lo más reducido posible, es decir,

Page 20: Curso Intro Duc to Rio de R

vamos a seleccionar un modelo de regesión. Para hacer esto contamos con la función step que selecciona un modelo de regresión a partir del criterio de información de Akaike (AIC, siglas en inglés). Creamos un estadístico que permite decidir el orden de un modelo. AIC toma en consideración tanto la medida en que el modelo se ajusta a las series observadas como el número de parámetros utilizados en el ajuste. Búscamos el modelo que describa adecuadamente las series y tenga el mínimo AIC. Veamos como lo presenta R:

> modelo8.1<-lm(final~test+exam1+exam2+labo,data=archivo) #modelo lineal> step(modelo8.1,direction="forward") #seleccionamos hacia delante Start: AIC= 303.37 final ~ test + exam1 + exam2 + labo

Df Sum of Sq RSS AIC- labo 1 99.2 19612.9 301.6- test 1 561.2 20074.9 302.8- exam2 1 614.5 20128.2 302.9<none> 19513.7 303.4- exam1 1 3429.8 22943.5 309.3

Step: AIC= 301.61 final ~ test + exam1 + exam2

Df Sum of Sq RSS AIC- exam2 1 661.8 20274.7 301.2<none> 19612.9 301.6- test 1 1645.0 21258.0 303.6- exam1 1 3601.0 23213.9 307.9

Step: AIC= 301.24 final ~ test + exam1

Df Sum of Sq RSS AIC<none> 20274.7 301.2- test 1 2511.8 22786.5 305.0- exam1 1 5469.7 25744.4 310.9

Call:lm(formula = final ~ test + exam1, data = archivo)

Coefficients:(Intercept) test exam1 25.9520 1.3026 0.7172

La forma que tiene de trabajar R parece bastante comprensible pero en mi caso estoy más acostumbrado a emplear el método forward de otro modo. Primero selecciono la variable candidata a entrar (la que mayor coeficiente de correlación lineal tenga con la variable dependiente) y posteriormente busco la variable que menor suma del cuadrado del error me produzca y después contrastamos si esa variable debe permanecer en el modelo. R lo que hace es marcar un AIC referencia y entran en el modelo todas las variables que tengan mayor AIC que ese valor referencia. En este caso por este método el modelo sería final=1.3test+0.71exam1, sólo se ha quedado con dos variables regresoras.

Page 21: Curso Intro Duc to Rio de R

Veamos este modelo como sería:

> modelo.FINAL<-lm(final~test+exam1,data=archivo)> summary(modelo.FINAL,cor=T) #incluimos cor=T para ver la correlación de los coeficientesCall:lm(formula = final ~ test + exam1, data = archivo)Residuals: Min 1Q Median 3Q Max -72.627 -12.149 2.902 16.257 34.708 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 25.9520 20.3937 1.273 0.209573 test 1.3026 0.5457 2.387 0.021143 * exam1 0.7172 0.2036 3.523 0.000977 ***---Signif. codes: 0 `***' 0.001 `**' 0.01 `*' 0.05 `.' 0.1 ` ' 1 Residual standard error: 20.99 on 46 degrees of freedomMultiple R-Squared: 0.451, Adjusted R-squared: 0.4271 F-statistic: 18.89 on 2 and 46 DF, p-value: 1.024e-06 Correlation of Coefficients: (Intercept) testtest -0.7179 exam1 -0.1935 -0.5326

Ahora imaginemos que nos interesa ver como funciona el modelo final de dos variables regresoras; si cumple las hipótesis (media del error 0, homocedasticidad, incorrelación, distribución normal del error). Esto fundamentalmente se puede ver de forma gráfica, las funciones R son muy sencillas, veámoslas:

> par(mfrow = c(2,2)) #con esto ponemos los 4 gráficos en la misma ventana> plot(modelo.FINAL) #pedimos los gráficos del modelo

Obteniendo en la ventana de gráficos:

Page 22: Curso Intro Duc to Rio de R

Figura 1

Parece que el modelo presenta heterocedasticidad como vemos en el gráfico de residuos studentizados frente a las predicciones y también vemos como hay algunas observaciones (las número 18, 36 y 45) que podrían ser potencialmente influyentes como nos indica el gráfico de las distancias de Cook Sin embargo el modelo si cumple las hipótesis de media 0 y distribución normal de los residuos.

La distancia de Cook del caso i-ésimo consiste en buscar la distancia entre los parámetros estimados si incluyen la observación i-ésima y si no la incluyen. Cada observación tiene su distancia y se considera significativa si es mayor que 1. Esta distancia se calcula con R con la función cooks.distance(objeto):

> cook<-cooks.distance(modelo.FINAL)> significativas<-cook>1> significativas 1 2 3 4 5 6 7 8 9 10 11 12 13 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 14 15 16 17 18 19 20 21 22 23 24 25 26

Page 23: Curso Intro Duc to Rio de R

FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 27 28 29 30 31 32 33 34 35 36 37 38 39 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 40 41 42 43 44 45 46 47 48 49 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

He creado el vector cook con las distancias y después el vector significativas que recoge una variable lógica. Como vemos ninguna observación supera el valor referencia 1, ninguna observación es potencialmente influyente. Otra forma de ver si una observación es potencialmente influyente es ver el potencial que tiene el caso i-ésimo, el peso que tiene la observación i-ésima a la hora de estimar la predicción. Si el potencial de una observación es alto tiene mucho peso a la hora de dar la predicción. Estos potenciales se obtienen matricialmente como la diagonal principal de la matriz HAT que se calcula a partir de la matriz de diseño del modelo que es la matriz de datos con la 1ª columna de unos. Hat es H, X es la matriz de diseño:       H=X(X'X)-1X'. La matriz de diseño se crea con la función model.matrix(objeto) y hat se crea a partir de esta matriz de diseño. Los elemento de la diagonal principal de hat son los potenciales sobre los que continuamos nuestro estudio:

> matriz.modelo<-model.matrix(modelo.FINAL) #creamos la matriz de diseño> potenciales<-hat(matriz.modelo)> potenciales<-hat(matriz.modelo) #creamos potenciales que contiene la matriz hat del modelo> plot(potenciales) #hacemos un gráfico de potenciales para ver los mayores> identify(potenciales) #identificamos sobre el gráfico el nº de la observación

Page 24: Curso Intro Duc to Rio de R

Esas son las observaciones con unos potenciales más altos, nos interesa que las observaciones tengan un potencial similar de aproximadamente el cociente de las variables regresoras (más uno por la columna de unos de X) entre el número de observaciones. Si se dobla esta cantidad estaríamos ante casos que hay que estudiar con detalle. Si además miramos el gráfico de las  distancias de Cook (Figura 1) vemos que las observaciones problemáticas  son la número 45 y 36. Estos casos podían influir en nuestro modelo.

Capitulo 9: Análisis de Componentes Principales.

El análisis de componentes principales puede encuadrarse dentro del conjunto de técnicas multivariantes conocidas como métodos factoriales (también se incluyen el análisis de factores y el análisis de correspondencias). Pretendemos sintetizar un gran conjunto de datos, crear estructuras de interdependencia entre variables cuantitativas para crear unas nuevas variables que son función lineal de las originales y de las que podemos hacer una representación gráfica. El objetivo del análisis de componentes principales será el reducir la dimensión de un conjunto de p variables a un conjunto m de menor número de variables para mejorar la interpretabilidad de los datos.

Page 25: Curso Intro Duc to Rio de R

Las nuevas variables, las componentes principales, determinan lo esencial de las variables originales, son una combinación lineal de ellas que además tienen unas propiedades interesantes:

1. son ortogonales (cada componente representa una dirección del espacio de las variables originales)

2. cada puntuación está incorrelada con la anterior 3. la primera componente es la que más varianza contiene y la j-ésima tiene más

varianza que la j-1 ésima... 4. las primeras j componentes dan la solución de mínimos cuadrados del modelo

Y=X B+E

Si hay relaciones estocásticas entre las p variables originales entonces podíamos condensar esa información en otras m variables que explican sólo la variación del sistema descartando la información redundante. Geométricamente el subespacio que creamos con las m primeras componentes da el mejor ajuste posible al conjunto de datos medido mediante la suma de los cuadrados de las distancias perpendiculares desde cada punto al subespacio. El subespacio de menor dimensionalidad sería m=1 componente podíamos hacer la representación en un sólo eje pero el conjunto inicial se podía distorsionar, así introduciríamos un nuevo eje para definir un subespacio m=2, perderíamos menos información. Si m=p tendríamos el mismo número de variables, no reduciríamos la dimensión, sólo haríamos una rotación rígida del conjunto de datos.

No voy a entrar en el algoritmo matemático para la obtención de las componentes, si haré alguna reseña en algún momento a términos matemáticos pero de momento no quiero entrar en fórmulas ni ecuaciones. Lo que si es cierto que con R las componentes se obtienen mediante cálculo matricial. Vamos a ver la forma de obtenerlas mediante un ejemplo:

Ejemplo 9.1:

Partimos del siguiente conjunto de datos: Se trata de datos de coches de importación y nacionales [Douglas Montgomery and David Friedman, "Prediction Using Regession Models with Multicollinear Predictor Variables" IIE Transactions (Mayo, 1993) vol. 25 nº 3, 73-85, Montgomery D.C. & Peck E.A., Introduction to Linear Regression Analysis, 2ª edición, J. Wiley and Sons, N.Y. (1992)] bajaté el archivo. Este conjunto de datos contiene las siguientes variables:

Variable Tipo Columnas Descripción añadida

desplazamiento numérico 1-5 en pulgadas cúbicas

potencia numérico 7-9 en ft-lbs

par motor numérico 11-13 en ft-lbs

razón de compresión numérico 15-17  

razón árbol trasero numérico 19-21  

nº de carburadores numérico 23  

velocidades numérico 25 cuantas

longitud del coche numérico 27-31 en pulgadas

Page 26: Curso Intro Duc to Rio de R

anchura del coche numérico 33-36 en pulgadas

peso del coche numérico 38-41 en lbs

tipo de transmisión numérico 43 0=manual 1=automático

recorrido gasolina numérico 45-48 en millas por galón de gasolina

Tenemos 12 variables de las que sólo seleccionaremos algunas, comencemos a trabajar con R:

> conjunto.datos<-read.table("c:\\datos\\GAS.TXT") #leemos el archivo> conjunto.datos V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V121 318.0 140 255 8.5 2.7 2 3 215.3 76.3 4370 1 19.72 440.0 215 330 8.2 2.9 4 3 184.5 69.0 4215 1 11.2...30 133.6 96 120 8.4 3.9 2 5 171.5 63.4 2535 0 23.9

De todas estas variables que contiene el archivo seleccionamos las que nos van a interesar y descartamos otras que no tienen mucha funcionalidad como puedan ser el número de marchas, el tipo de la trasmisión,... para quedarnos con otras características de los coches que nos permitan ver que tipos de coches tenemos e incluso clasificarlos. Nos quedamos con el desplazamiento, la potencia, el par motor, la longitud, la anchura, el peso y el recorrido en gasolina.

> attach(conjunto.datos)> conjunto<-data.frame(V1,V2,V3,V8,V9,V10,V12)> detach(conjunto.datos)> nombres<-c("desplazamiento","potencia","par","longitud","anchura","peso","recorrido")> names(conjunto)<-nombres

Ya tenemos el conjunto de datos con el que vamos a trabajar, también en este ejemplo se puede ver la función attach función que sirve para "atacar" un conjunto de datos, de este modo nos evitamos el llamar al conjunto con el símblo $. Sobre estas tres variables vamos a realizar el análisis de componentes principales muestrales. Para llevar a cabo este análisis hemos de realizar cálculos matriciales con la matriz de correlaciones y la matriz de varianzas covarianzas, estas dos matrices determinan los dos modos de obtención de las componentes, es decir, componentes principales a partir de la matriz de correlaciones y componentes principales a partir de la matriz de covarianzas.

Componentes a partir de la matriz de correlaciones:.

Si calculamos las componentes a partir de la matriz de correlaciones tendremos las componentes sobre las observaciones tipificadas de este modo nos evitamos los problemas de escala. Para la obtención de la matriz de componentes principales a partir de la matriz de correlaciones tendremos primero que hallar la matriz de correlaciones y esto se hace con la función cor que creo que ya vimos en algún capítulo anterior:

> matriz.correlaciones<-cor(conjunto)

Page 27: Curso Intro Duc to Rio de R

> matriz.correlaciones desplazamiento potencia par longitud anchuradesplazamiento 1.0000000 0.9406456 0.9895851 0.8670281 0.8001582potencia 0.9406456 1.0000000 0.9643592 0.8042467 0.7105117par 0.9895851 0.9643592 1.0000000 0.8662469 0.7881284longitud 0.8670281 0.8042467 0.8662469 1.0000000 0.8828869anchura 0.8001582 0.7105117 0.7881284 0.8828869 1.0000000peso 0.9531800 0.8879129 0.9435772 0.9559969 0.8994470recorrido -0.8718188 -0.7965605 -0.8493416 -0.7552211 -0.7624550 peso recorridodesplazamiento 0.9531800 -0.8718188potencia 0.8879129 -0.7965605par 0.9435772 -0.8493416longitud 0.9559969 -0.7552211anchura 0.8994470 -0.7624550peso 1.0000000 -0.8526911recorrido -0.8526911 1.0000000

Se aprecian unas altas correlaciones entre las variables, esto nos beneficia a la hora de realizar el análisis de componentes ya que se detectarán relaciones lineales entre variables y podemos investigar los patrones que unen las diferentes variables para crear unas nuevas variables que nos describan de forma más simple el conjunto de datos de coches con el que estamos trabajando. Ahora queda obtener las componentes, éstas son las combinaciones lineales de las variables que hacen máxima su varianza y esto se consigue obteniendo los autovalores y los autovectores de la matriz de correlaciones, no voy a explicar el razonamiento matemático, existen algunas páginas en la red donde os lo explican con bastante detalle. Sigamos trabajando con R:

> componentesI<-eigen(matriz.correlaciones)> componentesI$values[1] 6.193181539 0.400764875 0.244830693 0.094091951 0.046951262 0.015094646[7] 0.005085034$vectors recorrido peso anchura longitud par potenciadesplazamiento -0.3926641 0.2475231 0.05234234 0.03567111 0.61407897 0.01657661potencia -0.3733929 0.4647583 0.29963669 0.28335837 -0.65342114 -0.11954685par -0.3914349 0.2911694 0.16717164 0.11038560 0.28865783 0.44120895longitud -0.3744302 -0.3980948 0.31799457 -0.64622375 -0.22495520 0.33416791anchura -0.3560523 -0.6557118 -0.12419209 0.63919813 -0.04914155 0.11797501peso -0.3965847 -0.1523398 0.09815214 -0.17000242 0.15186737 -0.81350329

Page 28: Curso Intro Duc to Rio de R

recorrido 0.3590553 -0.1621960 0.86795951 0.22620880 0.19115713 -0.05826262 desplazamientodesplazamiento 0.63495457potencia 0.18235333par -0.66624254longitud 0.14256169anchura 0.05420171peso -0.31004382recorrido 0.01766344

El objeto componentesI recoge los autovalores y los autovectores de la matriz de correlaciones, el número de autovalores no nulos proporciona la dimensión del espacio en el que se encuentran las observaciones; un autovalor nulo revelaría la existencia de una dependencia lineal entre las variables originales. Pues si Z es la matriz de datos tipificados y R es la matriz de correlaciones con pares de autovalores y autovectores (l1,e1),(l2,e2),...,(lp,ep) entonces la i-ésima componente muestral viene dada por y=ei Z=e1i

z1+...+epi zp donde los autovalores son una observación genérica de las variables Z1,Z2,...Zp. La varianza total es la suma de los autovalores, y la varianza que explica la j-ésima componente es el autovalor j-ésimo dividido por el número de variables:

> componentesI$values[1]/7[1] 0.8847402

Con la primera componente explica ya un 88% de la variabilidad que es una cantidad más que suficiente para explicar correctamente las variables del conjunto de datos. Si queremos saber cuanto explicamos con la primera y la segunda variable:

> (componentesI$values[1]+componentesI$values[2])/7[1] 0.9419923

Con dos componentes retenidas explicamos ya un 94% de la variabilidad total. El número de componentes a retener depende de la cantidad de varianza que expliquen, en ese caso con la primera componente creo que sería suficiente. Algunas aplicaciones retienen las componentes cuyos autovalores asociados tienen un valor mayor que 1. Ahora nos queda por ver cual sería la componente:

> componetesI$vectors[1:7]desplazamiento potencia par longitud anchura -0.3926641 -0.3733929 -0.3914349 -0.3744302 -0.3560523 peso recorrido -0.3965847 0.3590553

Pues aquí tenemos la componente principal: Z1=-0.3926desplazamiento-0.3734potencia-0.3914par-0.3744longitud-0.356anchura-0.3966peso+0.359recorrido; toma valores muy parecidos para todas las variables excepto recorrido que es positiva esto se puede interpretar como a menor valor tome la variable componente mejor será el coche aunque hay que tener en cuenta que los coches buenos hacen un recorrido menor que los coches pequeños. Para ver como se comporta la componente hemos de introducir esta variable en el conjunto de datos para ver que

Page 29: Curso Intro Duc to Rio de R

valor toma para cada observación, esto lo podemos hacer introduciendo la fórmula para crear la nueva variable componente o con cálculo matricial. Lo voy a hacer con el cálculo matricial para que veáis como se trabaja con matrices en R:

> x<-as.matrix(conjunto) #x es la matriz del conjunto de datos 30x7> y<-as.matrix(componente.vector) #y es la matriz 7x1 con los valores de la componente> x %*% y #multiplicamos matrices y obtenemos una matriz 30x1 con los valores de la componente [,1] 1 -2110.7416 2 -2143.4584... 29 -2262.1919 30 -1218.8272

Se puede ver que para realizar operaciones con matrices es necesario incluir el símbolo %, ahora nos interesa ver la evolución de la componente en el conjunto de observaciones, para ello tenemos que unir matrices:

> componete.datos<-as.matrix(x %*% y ) #matriz de componentes> conjunto.final<-cbind(conjunto,componete.datos) #unimos matrices con la función cbind> conjunto.final desplazamiento potencia par longitud anchura peso recorrido componete.datos1 318.0 140 255 215.3 76.3 4370 19.7 -2110.74162 440.0 215 330 184.5 69.0 4215 11.2 -2143.45843 351.0 143 255 199.9 74.0 3890 18.3 -1928.37654 360.0 180 290 214.2 76.3 4250 21.5 -2107.22105 140.0 83 109 168.8 69.4 2700 20.3 -1280.03486 85.3 80 83 160.6 62.2 2009 36.5 -961.76797 350.0 165 260 200.3 69.9 3910 18.9 -1944.56198 96.9 75 83 162.5 65.0 2320 30.4 -1091.69239 351.0 148 243 215.5 78.5 4540 13.9 -2192.349510 440.0 215 330 231.0 79.7 5185 14.9 -2548.037811 171.0 109 146 170.4 66.9 2655 21.5 -1297.830412 302.0 129 220 199.9 74.0 3890 17.8 -1890.387813 350.0 155 250 196.7 72.2 3910 17.8 -1936.779514 318.0 145 255 197.6 71.0 3666 16.4 -1826.083315 231.0 110 175 179.3 65.4 3050 23.5 -

Page 30: Curso Intro Duc to Rio de R

1491.846516 96.9 75 83 165.2 61.8 2275 31.9 -1073.179017 500.0 190 360 224.1 79.8 5290 14.4 -2613.278818 231.0 110 175 179.3 65.4 3020 22.1 -1480.451619 350.0 170 275 199.6 72.9 3860 17.0 -1933.959420 250.0 105 185 196.7 72.2 3510 20.0 -1693.976421 225.0 95 170 194.0 71.8 3365 20.1 -1615.860322 89.7 70 81 155.7 64.0 1905 34.7 -917.186523 350.0 155 250 195.4 74.4 3885 16.5 -1927.628324 258.0 110 195 171.5 77.0 3375 19.7 -1641.741225 460.0 223 366 228.0 79.8 5430 13.3 -2669.619926 360.0 195 295 209.3 77.4 4215 13.8 -2102.220327 262.0 110 200 179.3 65.4 3180 21.5 -1566.079128 350.0 165 255 185.2 69.0 3660 16.5 -1838.345929 351.0 148 243 216.1 78.5 4715 13.3 -2262.191930 133.6 96 120 171.5 63.4 2535 23.9 -1218.8272

Vemos que los coches más potentes tienen un valor de la componente más bajo que los menos potentes, sin embargo recorren mucho menos espacio que éstos, se confirman los planteamientos que se hicieron con anterioridad. Con esta componente podemos saber que tipo de coche es cada uno sin necesidad de analizar todas las variables, si dispusiéramos de precios podíamos saber cual es más caro o más barato e incluso podemos ubicar otras observaciones.

Componentes principales a partir de la matriz de covarianzas:

Calcular las componentes a partir de la matriz de covarianzas no difiere mucho de calcularlas a partir de la matriz de correlaciones, elegir uno u otro método depende de las variables que tenemos en nuestro conjunto de datos. Variables con varianzas grandes tienden a asociarse con autovalores grandes y variables con varianzas pequeñas tiende a asociarse con autovalores pequeños, así pues sería conveniente el tipificar las unidades muestrales para que las variables sean comparables. Veamos que sucede en nuestro conjunto de datos:

> cov(conjunto) desplazamiento potencia par longitud anchura peso recorridodesplazamiento 13463.3826 4873.3970 9538.3428 2128.3800 527.21145 104071.183 -633.53025potencia 4873.3970 1993.6885 3576.9276 759.7257 180.14897 37305.897 -222.74678

Page 31: Curso Intro Duc to Rio de R

par 9538.3428 3576.9276 6900.5759 1522.3807 371.76759 73756.207 -441.86448longitud 2128.3800 759.7257 1522.3807 447.5874 106.06593 19031.538 -100.06382anchura 527.2114 180.1490 371.7676 106.0659 32.24510 4806.024 -27.11503peso 104071.1828 37305.8966 73756.2069 19031.5379 4806.02414 885435.586 -5024.97931recorrido -633.5303 -222.7468 -441.8645 -100.0638 -27.11503 -5024.979 39.22185

Vemos que las unidades son difícilmente comparables, sería conveniente el tipificar las observaciones. Desconozco si hay alguna función de R con la que podamos tipificar variables, por eso la mejor opción va a ser programarla:

> tipificar<-function(x){ (x-mean(x))/varianza(x)}

No tiene mayor complicación poco que comentar, la función varianza ya la teníamos creada en el capítulo 3; a partir de aquí vamos a realizar el análisis de componentes principales sin olvidar que estamos trabajando con los datos tipificados. El proceso es el mismo que con la matriz de correlaciones:

> datos.tipificados<-tipificar(conjunto)> componentesII<-eigen(cov(datos.tipificados))> componentesII$values[1] 578.5921014 3.1441794 1.7077434 1.2076084 1.0943170 0.5415443 0.2088097$vectors recorrido peso anchura longitud par potenciadesplazamiento 2.510359e-03 -0.019586489 0.106248291 -0.025785327 -0.982859312 0.145815869potencia 4.687239e-05 -0.589985214 0.792848158 0.107833661 0.097845596 0.026642031par -2.982895e-03 -0.797331687 -0.567048694 -0.061191845 -0.065755761 -0.160532844longitud 1.175570e-03 0.016218362 -0.116217484 0.991844352 -0.041956706 -0.022501828anchura -4.361458e-03 0.116691682 0.153377013 -0.012443462 -0.070359659 -0.668265795peso -9.999782e-01 0.001688000 0.001079292 0.001363264 -0.001682031 0.005744282recorrido 2.827855e-03 -0.043739740 -0.039073016 0.007117519 0.115656021 0.710731059 desplazamientodesplazamiento -0.019539430potencia 0.037384301par -0.094180712longitud -0.014393132anchura -0.714951066peso 0.001379889recorrido -0.691365696

Ahora la proporción de varianza debida a la k-ésima componente es lk/( l1 + l2 +...+ lp ) Esto traducido en R nos queda:

Page 32: Curso Intro Duc to Rio de R

> componentesII$values[1]/sum(componentesII$values)[1] 0.986523

De nuevo espectacular el resultado obtenido con la primera componente, explicamos con sólo una componente el 98% de la variabilidad de las variables que componen el conjunto de datos. A partir de aquí el trabajo sería completamente análogo al realizado con la matriz de correlaciones si bien con este método el análisis de componentes principales es aun mejor que con la matriz de correlaciones. Nos faltaría por analizar algún gráfico de componentes, seguro que en próximos capítulos veremos más posibilidades del análisis de componentes.

Capitulo 10: Análisis de conglomerados (cluster) I.

El proposito del análisis de conglomerados (cluster en terminología inglesa) es el agrupar las observaciones de forma que los datos sean muy homogéneos dentro de los grupos (mínima varianza) y que estos grupos sean lo más heterogéneos posible entre ellos (máxima varianza). De este modo obtenemos una clasificación de los datos multivariante con la que podemos comprender mejor los mismos y la población de la que proceden. Podemos realizar análisis cluster de casos, un análisis cluster de variables o un análisis cluster por bloques si agrupamos variables y casos. El análisis cluster se puede utilizar para:

La taxonomía, agrupar especies naturales. Para el marketing, clasificar consumidores tipo. Medicina, clasificar seres vivos con los mismos síntomas y características

patológicas. Técnicas de reconocimiento de patrones. Formar grupos de pixels en imágenes digitalizadas enviadas por un satélite

desde un planeta para identificar los terrenos. ...

Nosotros vamos a estudiar el análisis cluster de casos para el que podíamos partir de un análisis de componentes principales para evitar introducir variables no relevantes, puede servirnos de ejemplo el análisis de componentes principales que se realizó en el capítulo 9.

Ejemplo 10.1:

De nuevo empleo los ejemplos para introducir la metodología del análisis. Recordemos que realizamos un análisis de componentes principales a un conjunto de datos donde aparecían las carácterísticas de técnicas de distintos coches, a partir de la matriz de correlaciones se vió que con una componente podíamos explicar el 88% de la varianza total del conjunto de datos. Pues ahora vamos a realizar sobre el valor que toma esta componente para cada observación un análisis de agrupamiento. Primero de todo creamos el conjunto de datos sobre el que vamos a trabajar:

> x<-as.matrix(conjunto)> y<-componentesI$vectors[1:7]> comp.obs<-x %*% y> comp.obs

Page 33: Curso Intro Duc to Rio de R

[,1] 1 -2110.7416 ... 30 -1218.8272

Tenemos un conjunto de datos con 30 observaciones y una variable. En todo análisis cluster existen dos fases; en una primera fase a parir de los datos construimos una matriz de distancias o similaridades y después relaizamos el proceso de agrupación de individuos. Como paso previo es interesante realizar una representación gráfica de los datos para ver si se puede reconocer algún grupo:

No parecen que se formne grupos diferenciados pero prosigamos para ver si podemos aplicar una regla de agrupamiento. Disponemos de dos técnicas de formación de cluster: técnicas jerárquicas aglo:merativas de formación de conglomerados y técnicas no jerárquicas. En este ejemplo vamoa a emplear la técnica jerárquica que consiste en considerar en primera instancia cada observación como un cluster y posteriormente agrupar las obsevarciones más "similares", las observaciones que menos disten las unas de las otras, por eso lo primero que debemos hacer es calcularnos una matriz de distancias entre pares de observaciones. En este punto hago un inciso para explicar un aspecto de R que no había comentado hasta ahora. Con R podemos hacer multitud de

Page 34: Curso Intro Duc to Rio de R

análisis estadísticos y además existe un grupo de programadores que colaboran con más paquetes y más programas. Para poder emplear estos paquetes es necesario tenerlos en una librería library que en mi caso está en: C:\Archivos de programa\R\rw1051\library En esta librería tengo todos los paquetes de los que puedo disponer, pero cuando tu abres una sesión de R es necesario que carges el paquete que vas a emplear. Para hacer esto está la función library(nombre_librería) o bien abrimos el menú Packages de R y seleccionamos el paquete que queremos utilizar. Os he contado esto porque para realizar el análisis cluster necesitamos cargar en paquete mva:

> library(mva)

Ya estamos en disposición de poder empezar a realizar los cálculos pertinentes para nuestro análisis. Como hemos dicho antes lo primero es calcular la matriz de distancias y para ello tenemos la función dist:

> matriz.distancias<-dist(comp.obs)

Hemos creado una matriz diagonal de 30x30 a partir de la matriz de componente principales donde vienen recogidas las distancias. Por defecto dist calcula la distancia euclídea entre observaciones, si ejecutáis ?dist el archivo de ayuda os presenta las distintas distancias que se pueden calcular. Una vez obtenida esta matriz hemos de emplear la función hclust(<matriz_de_distancias>,method). En method indicamos por que método queremos que R realice los agrupamientos, veamos gráficamente los métodos más comunes:

Cluster simple method="single"Cluster completo

method="complete"Cluster promedio

method="centroid"

También tenemos el método Ward que es una técnica inferencial de formación de conglomerados que se basa en la minimización de la suma de cuadrados dentro de los cluster que se pueden formar. Por defecto el método que tieene hclust en "complete". Veamos como funciona hclust:

> clusterI<-hclust(matriz.distancias)> summary(clusterI) Length Class Mode merge 58 -none- numeric height 29 -none- numeric order 30 -none- numeric labels 30 -none- charactermethod 1 -none- character

Page 35: Curso Intro Duc to Rio de R

call 2 -none- call dist.method 1 -none- character

Hemos creado un objeto clusterI que contiene 7 variables a partir de las cuales realizaremos el análisis. R nos ha hecho las tareas de cálculo pero ahora somos nosotros los que tenemos que continuar determinando cuantos grupos se deben tomar y como analizar los grupos creados. Comenzamos "atacando" el objeto clusterI creado viendo la variable merge. Esta variable merge indica como se han ido formando los cluster:

> attach(clusterI)> merge [,1] [,2] [1,] -3 -23 #se unen la obs 3 y la obs 23 que forman el cluster '1' [2,] -13 -19 #se unen las 13 y 19 formando el '2' [3,] -1 -4 #la 1 y la 4 [4,] -26 3 #la 26 con el cluster 3 (observaciones 1 y 4) formando el '4' [5,] 1 2 #el cluster 1 y 2 formando de este modo el cluster '5' ...[27,] 24 25 #se unen el cluster 24 y 25[28,] 20 26 #el 20 y el 26[29,] 27 28 #el 27 y el 28

Esto nos ofrece una idea de la forma en la que se van uniendo, pero no podemos establecer una regla de unión entre observaciones, nos sería más útil ordenar el conjunto de datos de menor a mayor de forma que pudieramos hacer una regla de unión entre observaciones (recordemos que cuanto menor es el valor de la componente más potente y más grande es el coche) y de este modo podíamos ver intuitivamente la forma que tienen de unirse los datos. Para ordenar los datos empleamos la función sort:

> ordenado<-sort(comp.obs)> dist.ordenado<-dist(ordenado)> clusterII<-hclust(dist.ordenado)> attach(clusterII)> merge [,1] [,2] [1,] -13 -14 [2,] -11 -12 [3,] -7 -8 #los gama media [4,] -9 3 #enseguida se unen [5,] 1 2 [6,] -22 -23 #los más simples [7,] -16 -17 #se van uniendo [8,] -10 5 [9,] -24 -25[10,] -27 -28[11,] -19 -20[12,] -6 4[13,] -29 -30[14,] -15 8

Parece que los coches de gama media se unen enseguida, insistimos en que la componente principal ofrecía una medida de la potencia-prestaciones-tamaño de los

Page 36: Curso Intro Duc to Rio de R

coches, cuanto menor era la componente más potente, más rápido y más grande era el coche. Pues como decíamos los gama media se unen con facilidad, también ocurre esto con los coches más pequeños que son los siguientes en agruparse, por último son los coches "buenos" los que se van agrupando. Poco a poco los gama media se acercan a los coches buenos dejando de lado a las observaciones superiores a la 20ª como se puede ver en los pasos [18] con observaciones 24,25,26; [23] con observaciones 27,28,29,30 y [24] cuyas observaciones son 22,23,18,21,19,20 posteriormente en [25] y [27] se unen. Determinar el número de cluster con esta variable merge es bastante complicado por eso no puede servir mejor para analizar como se van creando los grupos. ¿Cómo determinar el número de cluster? En mi opinión la mejor manera es el análisis gráfico, el dendograma que es un gráfico de formación de cluster, para hacerlo se emplea la función plot.hclust(clusterII):

Este dendograma creo que puede admitir dos cortes que os expongo de manera gráfica para que me entendais mejor, los cortes los he realizado yo con el paint de windows, ya os explicaré como se puede hacer con R:

Page 37: Curso Intro Duc to Rio de R

Estas son las 2 opciones que yo planteo: en la primera opción se puede por un lado formar dos grupos donde tendríamos los coches medianos-grandes donde las observaciones 1, 2 y 3 parece que les cuesta unirse (son coches muy potentes y grandes) y donde las observaciones de 4 a la 16 son muy parecidos; y por el otro lado tenemos los coches utilitarios (observaciones de la 18 a la 30) que si se pueden considerar bastante parecidos entre sí aunque los hay un poco mejores. La segunda opción sería el hacer los cuatro grupos donde el grupo I encuadraría a los coches "menos malos" el grupo II a lo "malos", el grupo III a los "mejores" y el grupo IV a los "buenos".

Este es el análisis mediante el método completo, veamos el dendograma para el método promedio:

> clusterIII<-hclust(dist.ordenado,method="centroid")> plot.hclust(clusterIII)

Page 38: Curso Intro Duc to Rio de R

A la vista de este gráfico también podemos hacer tres grupos, además por este método se distinguen muy claramente las tres primeras observaciones como los mejores coches quedando más unidos los coches "menos malos" con los "buenos" con lo que se podía establecer un grupo que podían ser los utilitarios dentro de los cuales los hay mejoresy peores... Bueno de todas formas ya os he introducido a la metodología del análisis cluster con R así que debéis de ser vosotros los que hagais vuestro estudio y os planteéis vuestros objetivos y la forma de trabajar.

Capitulo 11: Análisis de conglomerados (cluster) II.

En este capítulo vamos a ver un par de ejemplos más de análisis de conglomerados con R. En el ejemplo del capítulo 10 partíamos de un conjunto de una sola variable que era la primera componente principal de un conjunto de datos que recogía características técnias de una serie de coches que se vendían es Estados Unidos, ahora vamos a ver dos ejemplo más donde tabajaremos con otras posibilidades de R.

Ejemplo 11.1:

Page 39: Curso Intro Duc to Rio de R

En este ejemplo vamos a trabajar con los datos de inflación de países de la Unión Europea. Los datos obtenidos a través de la página web del Instituto Nacional de Estadística de España vienen recogidos en un archivo excell, desconozco si existe algún paquete que me permita importar datos de excel a R (si lo hay para importar archivos SAS y SPSS), podemos trabajar con ficheros de texto pero al tratarse de 15 países y 3 variables (país, índice e incremento interanual) me parece más adecuado el introducirlos directamente en R creando tres vectores y uniéndolos de la forma más apropiada:

> nombres<-c("Alemania","Austria","Bélgica","España","Finlandia","Francia","Grecia","Holanda""Irlanda","Italia","Luxemburgo","Portugal","Dinamarca","Reino Unido","Suecia") > indices<-scan() #indice de precios al consumo1: 109 108.9 111.3 117.3 112.4 108.77: 125.8 119.5 122.4 114.3 113 119.113: 114.1 108.7 110.216: Read 15 items> tasa<-scan() #Incremento de la tasa interanual

1: 1 1.6 1.2 3.5 1.4 1.8 3.8 3.7 4.510: 1.8 2.2 3.8 2.5 1 1.2 16: Read 15 items

En este ejemplo vamos a separar los países inflacionistas de los no inflacionistas, ese va a ser nuestro objetivo, por ello partimos de un número predeterminado de cluster en este caso 2 (inflacionistas y no inflacionistas, insisto) y asignamos a cada individuo a un cluster mediante una técnica de ubicación iterativa a esta técnica se la conoce como el algoritmo de las k-medias. Pretendemos mejorar las clasificaciones minimizando las distancias utilizadas en la formación de los conglomerados. Sería siempre interesante empezar por la aglomeración jerárquica pero en este caso el objetivo de nuestro agrupamiento parece bastante claro y no es necesario comprobar cuantos cluster se pueden formar.

El siguiente paso con R es unir los dos vectores que contienen datos numéricos para formar el conjunto de datos sobre el que vamos a calcular la matriz de distancias con la que posteriormente realizaremos el análisis de agrupamiento. En este caso el método de

cálculo de la matriz de distancias es el método Manhattan que se utiliza habitualmente en variables dicotómbicas pero para que sigais conociendo posibilidades vamos a trabajar con ella:

> datos.inflacion<-cbind(indices,tasa)> matriz11.1<-dist(datos.inflacion,method="manhattan")

Veamos el gráfico de dispersión para identificar visualmente algún cluster:

Page 40: Curso Intro Duc to Rio de R

Si se identifican los cluster, arriba a la derecha tenemos los países con mayor tasa y abajo a la izquierda los de menor tasa de acumulación, ahora sólo nos queda plasmar esta idea inicial en R y ver la forma de agrupamiento de los países. Para realizar el algoritmo de las k-medias R dispone de la función kmeans(<matriz_distancias>,<num_cluster>), donde ambos argumentos son obligatorios ya que el número de cluster está prefijado:

> kmeans(matriz11.1,2)$cluster (1) [1] 1 1 1 2 1 1 2 2 2 1 1 2 1 1 1$centers (2) 1 2 3 4 5 6 7 81 2.356353 2.364722 2.035462 6.551598 2.266588 2.530643 14.912252 8.7150682 12.174428 12.140668 9.906339 3.547262 8.798775 12.300583 4.995479 2.386100 9 10 11 12 13 14 151 11.720213 3.325348 2.554850 8.355977 3.273403 2.530059 2.0242442 3.010035 6.879040 8.009260 2.462113 6.872028 12.465291 10.963804$withinss [1] 545.6604 591.0740$size (3) [1] 10 5

Esto es lo que no ofrece R. en (1) tenemos a que cluster se une cada observación, en (2) las distancias de cada observación al cluster y en (3) el tamaño de cada cluster. También aparece una función withinss que no sé para que sirve pero que ahí está, si alguien lo averigua que por favor me mande un correo. Ahora nos queda ver a que cluster pertenece cada país para ello unimos el vector nombres que creamos con anterioridad con la variable $cluster de el análisis, también unimos tasa e indices para ver mejor como funciona:

Page 41: Curso Intro Duc to Rio de R

> kmedias<-kmeans(matriz11.1,2)> cbind(nombres,kmedias$cluster,tasa,indices) nombres tasa indices [1,] "Alemania" "1" "1" "109" [2,] "Austria" "1" "1.6" "108.9" [3,] "Bélgica" "1" "1.2" "111.3" [4,] "España" "2" "3.5" "117.3" [5,] "Finlandia" "1" "1.4" "112.4" [6,] "Francia" "1" "1.8" "108.7" [7,] "Grecia" "2" "3.8" "125.8" [8,] "Holanda" "2" "3.7" "119.5" [9,] "Irlanda" "2" "4.5" "122.4"[10,] "Italia" "1" "1.8" "114.3"[11,] "Luxemburgo" "1" "2.2" "113" [12,] "Portugal" "2" "3.8" "119.1"[13,] "Dinamarca" "1" "2.5" "114.1"[14,] "Reino Unido" "1" "1" "108.7"[15,] "Suecia" "1" "1.2" "110.2"

Los menos inflacionistas los ha clasificado en el cluster 1 y los más inflcionistas como Holanda, Portugal,... y por supuesto mi querida España en el cluster 2. Si quisieramos ver este análisis de forma gráfica emplearíamos la función plot a la que la incluiremos unos argumentos para reconocer los cluster visualmente:

> plot(datos.inflacion,col=kmedias$cluster,pch=17,main="Agrupamiento")

En plot los argumentos que he añadido son los colores que van unidos al cluster asignado, el tipo de de símbolo que se cambia con pch (de 1 a 18) y el título con main, por lo demás comprobar que observaciones se unen con los cluster, si se quieren identificar sólo hay que emplear la función identify que ya vimos en un capítulo anterior.

Ejemplo 11.2:

Page 42: Curso Intro Duc to Rio de R

En este ejemplo vamos a agrupar distintos tipos de alimentos según sus aportes en calorías, proteínas, grasas y calcio. El conjunto de datos está en mi disco duro como un archivo de texto en el directorio datos (haz click aquí para ver el archivo) hemos de emplear la función read.table para importar el archivo a R:

> alimentos<-read.table("c:\\datos\\alimentos.txt",header=TRUE)> alimentos Alimentos Calorias Proteinas Grasas Calcio1 Hamburguesas 245 21 27 9.02 Buey 420 15 39 7.03 Pollo 115 20 3 8.04 Cordero 280 18 22 9.05 JamónAhumado 340 20 28 9.06 Cerdo 340 19 29 9.07 ChuletaCerdo 355 19 30 9.08 PescadoAzul 135 22 4 25.09 Sardinas 180 22 9 16.710 AtúnLata 170 25 7 12.311 MejillonesLata 155 16 9 15.712 MejillonesHervidos 200 19 13 15.0

Hay que reseñar el hecho de que para leer variables alfanuméricas no podemos tener espacios en blanco ya que la función read.table podía darnos problemas, para poder poner espacios en blanco en las variables alfanuméricas hay que dar un formato de entrada que todavía no hemos visto, por eso recomiendo siempre un vistazo previo al conjunto de entrada para evitar problemas. Como podéis ver en mi caso las observaciones de la variable Alimentos no tienen espacios en blanco y he juntado palabras para evitar estos problemas. es posible leer datos en blanco, leer archivos con diferentes delimitadores, cambiar el punto decimal por coma,... pero esto lo veremos en posteriores capítulos.

Ya tenemos el conjunto de datos con el que vamos a trabajar, como siempre tenemos la pega de que este conjunto tiene una variable caracter y a la hora de realizar cálculos sobre él nos puede plantear trastornos por eso hemos de separar la variable Alimentos o como suelo hacer yo unir el resto de variables (Calorías, Proteínas, Grasas y Calcio) en una matriz con la función cbind:

> attach(alimentos)> alimentos.2<-as.matrix(cbind(Calorías, Proteínas, Grasas, Calcio))> alimentos.2 Calorias Proteinas Grasas Calcio [1,] 245 21 27 9.0 [2,] 420 15 39 7.0 [3,] 115 20 3 8.0 [4,] 280 18 22 9.0 [5,] 340 20 28 9.0 [6,] 340 19 29 9.0 [7,] 355 19 30 9.0 [8,] 135 22 4 25.0 [9,] 180 22 9 16.7[10,] 170 25 7 12.3[11,] 155 16 9 15.7[12,] 200 19 13 15.0> detach()

Page 43: Curso Intro Duc to Rio de R

Ya podemos empezar a realizar nuestra labor matemática que en este caso vamos a emplear para el agrupamiento las medidas de disimilitud con base en la distancia euclidea pero que son todo lo contrario a las medidas de similitud que empleamos para los anteriores ejemplos, para hacer este ejemplo hemos de cargar la librería cluster:

> library(cluster)> disimilar<-daisy(alimentos.2)> disimilarDissimilarities : [1] 175.524927 132.204387 35.482390 95.010526 95.042096 110.059075 [7] 113.516519 67.891752 77.793894 92.162302 47.549974 307.159568[13] 141.074448 80.932070 80.746517 65.772335 287.789854 242.163354[19] 252.293658 266.836448 221.711524 166.105388 226.386837 226.501656[25] 241.518115 26.343880 65.883913 55.538185 41.367741 85.877820[31] 60.332413 60.415230 75.432089 147.040811 101.214080 111.287421[37] 125.868543 80.734132 1.414214 15.165751 207.028983 161.320457[43] 171.396879 186.136751 140.932608 15.033296 207.159359 161.456774[49] 171.554335 186.222689 141.039002 222.128341 176.449114 186.549966[55] 201.233422 156.044865 46.031402 37.473858 23.398504 66.445466[61] 11.504782 25.729361 20.685502 17.932094 31.293610 45.282337Metric : euclidean Number of objects : 12

Esa es la matriz de disimilaridades entre los valores de las observaciones que calcula R, a partir de ella vamos a hacer el agrupamiento, vamos a ver gráficamente el comprotamiento de ese agrupamiento y posteriormente determinaremos el número de cluster necesarios para llevar a buen puerto nuestro estudio:

> cluster11.2<-hclust(disimilar)> plot.hclust(cluster11.2)

> data.frame(alimentos$Alimentos,cluster11.2$order) alimentos.Alimentos cluster11.2.order1 Hamburguesas 22 Buey 73 Pollo 54 Cordero 65 JamónAhumado 16 Cerdo 47 ChuletaCerdo 128 PescadoAzul 99 Sardinas 1010 AtúnLata 311 MejillonesLata 812 MejillonesHervidos 11

Es bastante claro que tenemos dos cluster, por un lado están las observaciones 2, 7, 5, 6 y por el otro las restantes, para ver que alimentos son esas observaciones he unido la variable order (orden del dendograma) de cluster11.2 con el nombre de los alimentos para poder realizar una correspondencia visual entre los grupos y los nombres de los alimentos así el primer cluster sería buey, chuleta de cerdo, jamón ahumado y cerdo, es un extraño cluster pero continuemos con el estudio para ver porque se produce esta asociación.. ¿Qué ocurriría si tuvieramos una gran cantidad de observaciones y una referencia visual planterara problemas? En ese caso tras identificar el número de cluster

Page 44: Curso Intro Duc to Rio de R

emplearíamos una técnica por medios divisorios (Partitioning methods en terminología anglosajona) que situaría cada observación en los alguno de los cluster de forma que se minimizara la suma de las disimilaridades. Esto se hace con R del siguiente modo:

> cluster11.2b<-pam(alimentos.2,2)> cluster11.2bMedoids: Calorias Proteinas Grasas Calcio[1,] 170 25 7 12.3[2,] 340 19 29 9.0Clustering vector: [1] 1 2 1 2 2 2 2 1 1 1 1 1Objective function: build swap 37.89533 32.42881 Available components: [1] "medoids" "clustering" "objective" "isolation" "clusinfo" [6] "silinfo" "diss" "call" "data"

La función pam permite hacer lo que señalabamos antes, pero en este caso nos encontramos con que los cluster formados son distintos a los que formábamos con los métodos jerárquicos ya que el tamaño de los cluster es distinto que el tamaño anterior, como siempre veámoslo gráficamente que es como mejor se puede ver como trabajan las distintas funciones de R:

> par(mfrow=c(2,2))> plot(cluster11.2b)> plot(cluster11.2)

Page 45: Curso Intro Duc to Rio de R

Hemos dicho a R que nos ofrezca los gráficos en una pantalla dividida en 4 celdas con la función par y después graficamos los análisis con plot, vemos que la función pam ofrece 2 gráficos: uno de componentes principales y otro de distancias entre los centroides de los cluster. Vemos que cada método ha establecido distintos grupos, ahora comparemos las dos formas de agrupamiento:

> data.frame(alimentos$Alimentos,cluster11.2$order,cluster11.2b$clustering) alimentos.Alimentos cluster11.2.order cluster11.2b.clustering1 Hamburguesas 2 12 Buey 7 23 Pollo 5 14 Cordero 6 25 JamónAhumado 1 26 Cerdo 4 27 ChuletaCerdo 12 28 PescadoAzul 9 19 Sardinas 10

Page 46: Curso Intro Duc to Rio de R

110 AtúnLata 3 111 MejillonesLata 8 112 MejillonesHervidos 11 1

Alimento JerárquicosMétodos divisorios

Hamburguesa 1 1Buey 2 2Pollo 1 1Cordero 1 2(*)Jamón ahumado 2 2Cerdo 2 2Chuleta de cerdo 2 2Pescado azul 1 1Sardinas 1 1Atún en lata 1 1Mejillones en lata 1 1Mejillones hervidos

1 1

El problema lo hemos encontrado con el cordero que se ha unido al cluster 2 y en el análisis jerárquico se había unido al cluster 1. Como siguiente paso en nuestro ejemplo vamos a buscar una regla de funcionamiento para la agrupación de observaciones y esto lo hacemos sumarizando el objeto cluster11.2b que creamos con anterioridad:

> summary(cluster11.2b)Medoids: Calorias Proteinas Grasas Calcio (1)[1,] 170 25 7 12.3[2,] 340 19 29 9.0Clustering vector: (2) [1] 1 2 1 2 2 2 2 1 1 1 1 1Objective function: build swap 37.89533 32.42881 Numerical information per cluster: (3) size max_diss av_diss diameter separation [1,] 7 77.79389 33.07663 132.2044 35.48239 [2,] 5 80.74652 31.52185 141.0744 35.48239Isolated clusters: L-clusters: character(0) L*-clusters: character(0)Silhouette plot information: (4) cluster neighbor sil_width 11 1 2 0.7879602 10 1 2 0.7839538 9 1 2 0.7648888 8 1 2 0.7563286 3 1 2 0.7093818 12 1 2 0.6655977 1 1 2 0.1340588

Page 47: Curso Intro Duc to Rio de R

7 2 1 0.7681916 6 2 1 0.7680220 5 2 1 0.7675267 2 2 1 0.6322059 4 2 1 0.2312497 Average silhouette width per cluster: [1] 0.6574528 0.6334392 Average silhouette width of total data set: [1] 0.6474471Dissimilarities : [1] 175.524927 132.204387 35.482390 95.010526 95.042096 110.059075 [7] 113.516519 67.891752 77.793894 92.162302 47.549974 307.159568 [13] 141.074448 80.932070 80.746517 65.772335 287.789854 242.163354 [19] 252.293658 266.836448 221.711524 166.105388 226.386837 226.501656 [25] 241.518115 26.343880 65.883913 55.538185 41.367741 85.877820 [31] 60.332413 60.415230 75.432089 147.040811 101.214080 111.287421 [37] 125.868543 80.734132 1.414214 15.165751 207.028983 161.320457 [43] 171.396879 186.136751 140.932608 15.033296 207.159359 161.456774 [49] 171.554335 186.222689 141.039002 222.128341 176.449114 186.549966 [55] 201.233422 156.044865 46.031402 37.473858 23.398504 66.445466 [61] 11.504782 25.729361 20.685502 17.932094 31.293610 45.282337Metric : euclidean Number of objects : 12 Available components: [1] "medoids" "clustering" "objective" "isolation" "clusinfo" [6] "silinfo" "diss" "call" "data"

En (1) tenemos la media de cada variable dentro del cluster, los alimentos "sanos" con menor aporte calórico, menos grasas y más calcio forman el cluster 1 y los "menos sanos" forman el cluster 2. En (2) tenemos el vector que coloca cada observación en un cluster. En (3) tenemos información numérica sobre cada cluster como el tamaño, distancias medias y máximas,... En (4) tenemos como funciona el algoritmo que clasifica las observaciones, le funcionamiento es análogo a la función hclust. Este ha sido el estudio que al final nos ha ofrecido una buena función clasificatoria de alimentos aunque en un principio planteara algunas dudas, de todas formas yo sigo sin entender como ha clasificado a las hamburguesas como un alimento "sano"...

Page 48: Curso Intro Duc to Rio de R

Capitulo 12: Introducción al análisis de la varianza.

Este capítulo quizá debía haber sido el siguiente a los capítulos dedicados a la modelización pero por ser muy extenso lo he ido dejando porque me parecía interesante manejar matrices (Capítulo 9: Componentes principales) y manejar paquetes y análisis gráficos de mayor nivel (Capítulos 10 y 11). El análisis de la varianza nos es imprescindible para posteriormente desarrollar los capítulos dedicados al muestreo y métodos de remuestreo que pretendo que sean los capítulos estrella de este pequeño curso que voy contruyendo en mis ratos libres.

Comencemos estableciendo conceptos. Lo primero que hacemos es plantear una hipótesis que va a motivar un experimento, elegimos el diseño para nuestro experimento y recogemos los datos y los analizamos mediante el análisis de la varianza que consiste en descomponer la variabilidad total de los datos en sumandos cada uno de ellos asignable a una fuente de variación; posteriormente ya sacamos conclusiones. Lo que voy a contar viene recogido en los libros:

*MONTGOMERY, D.C.: Diseño y Análisis de Experimentos. Grupo Editorial Iberoamérica, 1991.

*PEÑA, D.: Estadística: Modelos y Métodos, vol. II: Modelos Lineales y Series Temporales, Alianza Universidad Textos, 1992

En concreto "el montgomery" es el lbro que seguí en mi etapa de estudiante de estadística y es el que empleo para hacer estas líneas.

Conceptos y definiciones:

Variable repuesta: Variable cuantitativa sobre la que realizamos el estudio asociada al experimento.

Factor: Condiciones que se manipulan en un experimento que afectan a la variable respuesta.

Nivel de un factor: Maneras de presentarse un factor

Tratamientos: Condiciones bajo las cuales se realiza el experimento, son convinaciones de factores.

Unidades experimentales: Sujetos sometidos a los tratamientos sobre los que se mide la variable respuesta.

Réplica: observación adicional de un mismo tratamiento.

Para diseñar un experimento se tienen en cuenta como son las unidades experimentales y la asignación de tratamientos. Según esto tenemos estructuras de diseño y estructuras de tratamiento:

Estructuras de diseño:

Page 49: Curso Intro Duc to Rio de R

Diseño completamente aleatorizado. Diseño por bloques aleatorizados completos. Diseño de cuadrados latinos.

Estructuras de tratamiento:

Diseño unifactorial. Diseño bifactorial. Diseño n factorial. Diseño 2^n. diseño anidado.

Comenzamos con el diseño más básico de todos:

Diseño unifactorial completamente aleatorizado:

Partimos de unidades experimentales homogéneas y queremos estudiar la influencia de un solo factor midiendo la variable respuesta. La tabla del análisis de la varianza (ANOVA) es:

Fuente de variaciónSumas de cuadrados

Grados de Libertad

Cuadrados Medios

Test F

Factor grupos tratamientos(BETWEEN)

SCTr a-1 CMTr=SCTr/a-1 U=CMTr/CME

Error(WITHIN) SCE N-a CME=SCE/N-a  Total SCT N-1    

Para realizar el análisis de la varianza con R hemos de determinar el modelo con el que queremos trabajar. Si recordamos en el capítulo 7 para crear el objeto modelo lineal empleábamos la función lm(Y~X), creábamos el modelo probabilístico Y=X+e de variables cuantitativas, ahora vamos a crear otro modelo probabilístico Yij=media_i+e_ij donde la media_i es una constante conocida que es la respuesta media bajo el tratamiento i y e_ij es la parte probabilísitica que cumple una serie de condiciones. Sobre este modelo realizaremos el análisis de la varianza con la función aov(Y~X) donde Y es la variable respuesta que es la variable cuantitativa asociada al experimento y X es la condición bajo la cual mido la variable respuesta, X es el factor.

Como siempre veamos como trabajar con R mediante un ejemplo:

Ejemplo 12.1:

En un tratamiento contra la hipertensión se seleccionaron 40 enfermos de características similares. A cada enfermo se le administró uno de los fármacos P, A, B, AB, al azar, formando 4 grupos. El grupo P tomó placebo (fármaco inocuo), el grupo A tomó un fármaco "A", el grupo B un fármaco "B" y el grupo AB una asociación entre "A" y "B". Para valorar la eficacia de los tratamientos, se registró el descenso de la presión diastólica desde el estado basal (inicio del tratamiento) hasta el estado al cabo de una semana de tratamiento. Los resultados, después de registrarse algunos abandonos, fueron los siguientes: P: 10, 0, 15, -20, 0, 15, -5

Page 50: Curso Intro Duc to Rio de R

A: 20, 25, 33, 25, 30, 18, 27, 0, 35, 20 B: 15, 10, 25, 30, 15, 35, 25, 22, 11, 25 AB: 10, 5, -5, 15, 20, 20, 0, 10

¿Tenemos diferencias entre los tratamientos?

Introducimos los datos:

> presion<-c(10, 0, 15, -20, 0, 15, -5 + ,20, 25, 33, 25, 30, 18, 27, 0, 35, 20 + ,15, 10, 25, 30, 15, 35, 25, 22, 11, 25, + 10, 5, -5, 15, 20, 20, 0, 10 )> grupos<-c("P","P","P","P","P","P","P","A","A","A","A","A","A","A","A","A","A",+ "B","B","B","B","B","B","B","B","B","B","AB","AB","AB","AB","AB","AB","AB","AB")> grupos<-factor(grupos)> grupos [1] P P P P P P P P A A A A A A A A A A B B B B B B B [26] B B B AB AB AB AB AB AB AB ABLevels: A AB B P

Hemos creado dos vectores presion que recoge la variable respuesta y grupos que recoge el factor, para su creación hemos de emplear la función factor con ella R reconoce el tipo de variable que contiene ese vector creando un vector de factores. Realicemos el análisis de la varianza, con él haremos el contraste de igualdad de medias para establecer si hay diferencias significativas entre las medias de los distintos grupos:

> unifact<-aov(presion~grupos)> summary(unifact) Df Sum Sq Mean Sq F value Pr(>F) grupos 3 2492.61 830.87 8.5262 0.0002823 *** Residuals 31 3020.93 97.45 ---Signif. codes: 0 `***' 0.001 `**' 0.01 `*' 0.05 `.' 0.1 ` ' 1

Se rechaza la hipótesis nula de igualdad de medias en *** que planteamos con el test F así pues hay diferencias entre los tratamientos. Para ver cual de estos tratamientos son diferentes contamos con métodos de test de recorrido estudentizado y con métodos de contrastes múltiples. Con R podemos programar el test que nos interese, pero el módulo base tiene test de recorrido estudentizado. En este caso vamos a ver el test de Tuckey que compara todas las posibles medias dos a dos y basándose en una distribución q alfa(k,n) del rango estudentizado determina una diferencia mínima significativa para que dos medias sean distintas. En R el test de Tukey se realiza con la función TuckeyHSD:

> TukeyHSD(unifact) Tukey multiple comparisons of means 95% family-wise confidence level Fit: aov(formula = presion ~ grupos)$grupos diff lwr upr

Page 51: Curso Intro Duc to Rio de R

AB-A -13.925000 -26.6337332 -1.216267 B-A -2.000000 -13.9819085 9.981909 P-A -21.157143 -34.3605630 -7.953723 B-AB 11.925000 -0.7837332 24.633733 P-AB -7.232143 -21.0985076 6.634222 P-B -19.157143 -32.3605630 -5.953723

Ya tenemos las diferencias, ahora necesitamos compararlas con la diferencia mínima que se considera significativa, para esto contamos con la distribución q de recorrido estudentizado, que se determina en R con: qtukey(p, nmeans, df), donde p es la probabilidad (alfa), nmeans es el número de niveles y df los grados de libertad que serán N-a como en el error. Al valor de esta distribución hay que multiplicarle la raiz cuadrada de la división de la estimación de la varianza (CME=SCE/N-a ) por el número de tratamientos, esto es por la forma en que creamos la diferencia de medias. En caso de tener un diseño balanceado dividimos por el mínimo de tratamientos como es nuestro caso. Todo esto traducido a R:

> (qtukey(0.05,4,31))*sqrt(97.45/7) [1] 2.819698

Este es el valor referencia, valores absolutos por encima de éste ya consideramos diferencias significativas. De nuevo repetir como se halla este número: qtukey(0.05,4,31) calcula el valor de la distribución q de Tukey para 0.05 ya que estamos con una confianza del 95%, 4 niveles y 31 grados de libertad; sqrt(97.45/7) 97.5 es la estimación de la varianza (el cuadrado medio del error) que se encuentra en la tabla ANOVA y 7 el mínimo número de tratamientos que son los pacientes que tomaron placebo. El valor de de 2.82 luego sólo la diferencia entre A y B se puede considerar que no es significativa, no hay diferencias entre los pacientes que tomaban A o B, sin embargo si hay diferencias entre todos los demás.

En resumen se puede determinar que los pacientes que han tomado placebo o la convinación entre ambos medicamentos AB han tenido una mayor reducción de la presión diastólica desde el estado basal (inicio del tratamiento) hasta el estado al cabo de una semana de tratamiento, siendo el placebo el tratamiento que más ha hecho reducir dicha presión.