Está en la página 1de 83

Tutorial R

Métodos de Investigación Cuantitativa


Pablo De Tezanos-Pinto
padeteza@uc.cl
2012-2017
Para este tutorial vamos a ocupar RStudio (disponible en http://www.rstudio.com/), porque facilita un poco
las cosas. En todo caso, los comandos funcionan exactamente igual en cualquier programa que ocupe R.
La idea es que lean esto directamente en RStudio para que puedan ir ejecutando los comandos a medida que
avanzamos. Si bien no es necesario, puede ser una buena idea que vayan escribiendo en este mismo archivo
sus comentarios, e intentando hacer los análisis por su cuenta con otras variables o con su propia base de
datos.

Configuración de RStudio.
Dependiendo de la configuración de su computador, puede que no alcancen a ver bien este texto. En ese caso,
les recomiendo ajustar esta ventana con el mouse y cambiar el tamaño de la letra (en Tools -> Options ->
Appearance).
También pueden aprovechar de cambiar otra configuración importante, en Tools -> Options -> General.
“Save workspace to .RData on exit” dice “Ask”. Debería decir “Always”. De esta forma, los objetos que vamos
a ir creando van a quedar guardados para la próxima vez que abran el programa.

Introducción a R
R funciona escribiendo comandos en esta ventana -el editor- o en la consola -la ventana justo abajo de ésta.
En general, los comandos están compuestos de dos cosas: una función y un objeto.
Las funciones son simplemente procesamientos que le pedimos a R, por ejemplo
2 + 2
## [1] 4
o
mean(c(1,4,7,3,2))
## [1] 3.4
o incluso
help(mean)
son ejemplos de funciones. Si están leyendo esto en RStudio, pueden ejecutar cada una de las funciones
presionando “ctrl + Enter” (en Mac, es “Command + Enter”) en la línea correspondiente. El resultado de la
función va a aparecer abajo, en la consola, con la excepción de help(), que abre el archivo de ayuda de R, en
este caso con información sobre la función mean().
La idea es que a medida que avanzan en este tutorial vayan ejecutando todas las funciones que estamos
revisando.
Normalmente, los resultados de las funciones son asignados a objetos, lo que permite seguir trabajando con
esos resultados. Por ejemplo, en vez de 2 + 2, podemos escribir

1
resultado = 2+2 # (presionar "ctrl + Enter" para crear el objeto)
Esto asigna el resultado del código 2 + 2 a un objeto llamado “resultado” (Podríamos haber puesto cualquier
nombre.) En la ventana de la derecha (Workspace), RStudio lista los objetos que hemos creado. La gracia es
que ahora podemos seguir trabajando con este objeto:
resultado + 1
## [1] 5
es igual a 5, y si lo ejecutan el resultado va a aparecer en la consola. Si ejecutan simplemente resultado, R
entrega el valor asignado a este objeto.
resultado
## [1] 4
Los objetos pueden ser el resultado de cualquier operación, incluyendo los resultados de análisis estadísticos,
bases de datos, tablas, listas y variables.
La función remove() elimina el objeto de su espacio de trabajo. También pueden ocupar ls() para ver una
lista de los objetos creados.
ls()
## [1] "resultado"
Un detalle importante. . . en R las mayúsculas y minúsculas no son lo mismo.
Resultado # y
Help(mean)
van a generar un mensaje de error en la consola, porque no son lo mismo que resultado y help(mean).

Librerías de R

Una de las principales virtudes de R es que el código es abierto (open source), lo que permite que sea
desarrollado y actualizado permanentemente y que distintas personas puedan extender este programa
desarrollando “paquetes” o “librerías” para que R sea capaz de realizar nuevos análisis.
Por ejemplo, una librería que vamos a ocupar bastante es “psych”, que incluye una serie de funciones
típicamente utilizadas en investigación en psicología.
Antes de poder utilizar estas funciones en R, es necesario instalar “psych”. Para esto, pueden ir a menú
“Packages” en la ventana de abajo a la derecha -al lado de “Help”- presionar el botón “Install” y escribir
“psych” en el cuadro de diálogo. Esto va a descargar la librería e instalarla en su computador. Como siempre,
también es posible (y más fácil) hacer esto ocupando una función, en este caso:
install.packages("psych") # El progreso de la instalación aparece en la consola.
# requiere estar conectado a internet!
Luego de que una librería ya está instalada, es necesario abrirla antes de poder ocupar sus funciones. Es una
buena idea agregar las librerías utilizadas al comienzo del archivo con los análisis. La función para cargar
una librería instalada es
library(psych)
Si abren el archivo de ayuda de esta librería,
help(psych)
pueden ver una descripción de todas las nuevas funciones que ahora están disponibles. Además de funciones,
esta librería incluye bases de datos que podemos ocupar como ejemplos. El comando

2
personalidad = epi.bfi # la librería psych tiene que estar instalada y cargada
crea un nuevo objeto, una base de datos llamada “personalidad”, ocupando los datos disponibles en la
librería psych (epi.bfi). La base de datos incluye 13 variables de personalidad medidas en 231 personas. Esta
información aparece en la ventana de la derecha (Workspace), donde se listan los objetos que hemos creado
en nuestro espacio de trabajo. En RStudio, pueden hacer click en este objeto para ver los datos, o ejecutar
View(personalidad)
Pueden ver más información sobre esta base de datos ejecutando
help(epi.bfi)
Simplemente a modo de ejemplo, ahora podemos pedir un dispersiograma que muestra la relación entre
extraversión y apertura a la experiencia. Este comando tiene dos líneas (aunque podría haberlo escrito en
una), por lo que antes de ejecutarlo tienen que seleccionar ambas.
with(personalidad,
plot(bfext,bfopen))
160
140
bfopen

120
100
80

50 100 150

bfext
El gráfico que aparece en “Plots” muestra que en general las personas más extrovertidas tienen también
mayores puntajes de apertura a la experiencia.
Antes de terminar esta sección me gustaría notar la importancia de escribir una sintaxis ordenada. Obviamente,
a R le da exactamente lo mismo si la sintaxis está ordenada o no. ¡Pero R no es el único que tiene que leerla!
Para los lectores humanos -para ustedes mismos y para las personas con quienes colaboran- es mucho más
fácil entender una sintaxis ordenada:
a) Escojan nombres amigables para las variables y los objetos. Es decir, nombres que sean cortos pero que
sean legibles y describan de qué estamos hablando. Por ejemplo, “bfext” es un nombre relativamente
bueno (se refiere al constructo extroversión en el contexto de una medición de personalidad “big five”);
bffac3 (factor 3 de la medición big-five), en cambio, es mucho menos descriptivo. Aunque puedo
imaginarme peores nombres.
b) Ocupen generosamente la opción de hacer comentarios en la sintaxis. Cualquier texto que sea precedido
por un signo # es ignorado por R, pero puede ser tremendamente útil para quien está leyendo y tratando
de entender la sintaxis.

3
c) Indenten los comandos de forma que sean más fáciles de entender. El ejemplo del gráfico de dispersión
que acabamos de hacer
with(personalidad,
plot(bfext,bfopen))
está indentado porque esto facilita su interpretación. La primera línea indica que el comando será ejecutado
usando la base de datos “personalidad”, y la segunda línea indica que se está pidiendo un gráfico que relacione
las variables bfext y bfopen. Para comandos más complicados, con varias líneas, indentar hace una diferencia
mucho mayor. RStudio indenta automáticamente, en todo caso. (Ver en “Opciones”, “Código” si algo no
funciona.)

Explorando una base de datos


Abrir una base de datos en R puede ser un proceso complicado, pero para eso está este tutorial. En verdad
no tiene por qué ser complicado. Típicamente se ocupa Excel para digitar los datos de un estudio. Si bien es
posible importar directamente los datos desde Excel, lo más fácil es guardar los datos en formato de texto.
Específicamente, les recomiendo guardar los datos en formato .csv (comma separated values). Todo lo que
tienen que hacer es abrir el archivo Excel, poner “guardar como” y seleccionar este formato. En este tutorial
incluye una base de datos en Excel llamada alumnos2012.xlsx, que tiene los datos de un estudio hecho con
los alumnos del curso durante el año 2012, en que grupos de alumnos generaron varias preguntas para medir
distintos constructos. Incluye temas tan diversos como las actitudes hacia el aborto, hacia el Starbucks en la
universidad y el horóscopo de cada alumno. El archivo alumnos2012.pdf contiene más información sobre
esta base de datos, que vamos a ocupar como ejemplo a lo largo de este tutorial.
Abran los datos en Excel, y guárdenla como alumnos2012.csv (valores separados por comas) en la misma
carpeta donde está este archivo (Tutorial R.R). Es posible abrir el archivo sólo con comandos, pero también
es posible abrirlo ocupando un menú. Pueden hacer esto en la ventana de “Workspace” presionando el botón
“Import Dataset”, o pueden ocupar el siguiente comando para abrir un cuadro de diálogo. Creo que en general
es importante hacerlo con comandos, porque así queda un registro de la necesidad de abrir una base de datos
para continuar. El comando
estudio2012 = read.csv(file.choose(),
header = TRUE) # abrir archivo alumnos2012.csv
abre un cuadro de diálogo donde pueden seleccionar el archivo alumnos2012.csv. Les recomiendo que siempre
pongan un comentario indicando el nombre del archivo que hay que abrir -en beneficio de sus colaboradores y
de ustedes mismos.
Dependiendo de la configuración del computador, es posible que el archivo está separado por ; en vez de comas
(porque en español se ocupa coma para indicar decimales). En este caso, hay que explicitar el separador.
estudio2012 = read.csv(file.choose(), # abrir archivo alumnos2012.csv
header = TRUE,
sep=";") # Ocupar ; como separador
En detalle, este comando hace lo siguiente:
estudio2012 = # crea un objeto llamado estudio2012
read.csv( # lee un archivo .csv
file.choose(), # abre un cuadro de diálogo para elegir un archivo
header = TRUE # indica que la primera línea del archivo
) # incluye los nombres de las variables.
Si todo salió bien, ahora tienen un objeto llamado estudio2012 en su espacio de trabajo. Pueden hacer click
sobre este objeto para mirar los datos. El estudio incluye 84 variables medidas en 112 alumnos.

4
Una buena práctica es tener este archivo (con los comandos) y la base de datos en la misma carpeta. Pueden
definir esta misma carpeta como su directorio de trabajo (“working directory”), lo que permite leer y escribir
archivos sin tener que poner la dirección completa.
getwd() # obtiene su directorio de trabajo, pueden cambiarlo en el menú "Sesión"
# o en la pestaña "Archivos"
Si estudio2012.csv está en su directorio de trabajo, pueden ocupar
estudio2012 = read.csv("alumnos2012.csv", header = TRUE) # o agregando sep = ";"
para cargar el archivo. Esta es la opción más simple, y la mejor. Después pueden abrir o guardar otros
archivos sin tener que especificar donde, porque se hace por defecto en el directorio de trabajo, que debiera
ser siempre el mismo directorio donde tienen el archivo con su código.
Un detalle técnico. . .
Si se fijan, el archivo se llamaba alumnos2012 pero el objeto que creamos se llama estudio2012. Esto es
precisamente para que quede claro que el archivo con los datos y la base de datos que creamos en R son cosas
distintas. Pueden modificar todo lo que quieran el objeto de R, y eso no va a cambiar el archivo original con
los datos. ¡Esto es tremendamente bueno para su paz mental! En caso de cualquier problema, simplemente
pueden volver a cargar los datos originales.
El comando
names(estudio2012)
## [1] "n" "sitsent" "desconf1" "desconf2" "desconf3" "desconf4"
## [7] "desconf5" "vidau1" "vidau2" "vidau3" "vidau4" "vidau5"
## [13] "starb1" "starb2" "starb3" "starb4" "starb5" "ayude1"
## [19] "ayude2" "ayude3" "ayude4" "ayude5" "abor1" "abor2"
## [25] "abor3" "abor4" "abor5" "tolsex1" "tolsex2" "tolsex3"
## [31] "tolsex4" "tolsex5" "intex1" "intex2" "intex3" "intex4"
## [37] "intex5" "acogex1" "acogex2" "acogex3" "acogex4" "acogex5"
## [43] "ansev1" "ansev2" "ansev3" "ansev4" "ansev5" "insom1"
## [49] "insom2" "insom3" "insom4" "insom5" "intui1" "intui2"
## [55] "intui3" "intui4" "intui5" "valma1" "valma2" "valma3"
## [61] "valma4" "valma5" "streu1" "streu2" "streu3" "streu4"
## [67] "streu5" "intay1" "intay2" "intay3" "intay4" "intay5"
## [73] "tprej1" "tprej2" "tprej3" "tprej4" "tprej5" "genero"
## [79] "zodiaco" "orienpol" "mencion" "votop" "herman" "lugar"
nos entrega los nombres de todas las variables incluidas en la base de datos.
Probablemente nadie se va a aprender de memoria todos los nombres de las variables, por lo que names() es
un comando tremendamente útil.
Una de las primeras cosas que debiéramos hacer cuando abrimos una base de datos es revisar los descriptivos
para cada una de las variables. Más allá de ser una primera mirada a los resultados del estudio, esto permite
identificar cualquier error en la digitación o en la construcción de la base de datos.
describe(estudio2012)
## vars n mean sd median trimmed mad min max range skew
## n 1 112 56.50 32.48 56.5 56.50 41.51 1 112 111 0.00
## sitsent* 2 112 2.94 0.98 3.0 2.93 1.48 1 4 3 0.07
## desconf1 3 111 4.47 1.66 5.0 4.54 1.48 1 7 6 -0.51
## desconf2 4 111 3.45 1.80 3.0 3.37 2.97 1 7 6 0.19
es una función de la librería psych que entrega los descriptivos de cada una de las variables. En cuanto a la
calidad de la base de datos lo más importante es revisar el n, que nos indica la cantidad de personas que

5
contestaron cada pregunta (un n de cero en una pregunta probablemente refleja un error en la creación de la
base de datos) y el rango de respuesta (min y max). Las preguntas del cuestionario tenían un rango de 1 a 7;
claramente habría un error en la base de datos si en alguna pregunta el rango fuera distinto (de 1 a 34, por
ejemplo).
Además de esto, describe() entrega una buena cantidad de información descriptiva. El promedio, la mediana,
la desviación estándar y el grado de asimetría (skew).
Algunas de las variables tienen un * junto a su nombre. Esto significa que son variables categóricas (porque
están codificadas como texto en la base de datos). La variable sitsent (situación sentimental) incluía tres
opciones,
table(estudio2012$sitsent)
##
## En una relacion Es complicado Soltero/a
## 1 54 8 49
El promedio de esta variable no tiene ningún sentido. R simplemente asigna un número a cada categoría y la
función describe() promedia todas las variables, aunque sean categóricas.

Descriptivos.
La información descriptiva entregada con el comando describe() es más que suficiente para tener una buena
idea del comportamiento de las variables. En general, vamos a estar interesados en el promedio mean(), la
mediana median() y la desviación estándar sd(). Todos estos indicadores pueden ser solicitados con su
propio comando.
En la mayoría de las situaciones vamos a querer referirnos a variables específicas, no a la base de datos
completa como hicimos con describe(estudio2012). Como en R podemos tener múltiples bases de datos en
nuestro espacio de trabajo, es necesario indicar tanto el nombre de la variable como la base de datos a la que
pertenece. Hay dos formas principales para hacer esto, y pueden ocupar cualquiera de las dos dependiendo
de lo que sea más fácil para cada situación.
La primera es ocupar el signo $ para indicar base de datos y el nombre de la variable:
mean(estudio2012$insom1, na.rm=TRUE)
## [1] 3.441
En este comando, se pide el promedio de la variable insom1 en la base de datos estudio2012. La función
mean() requiere especificar qué hacer con los datos perdidos (la gente que no contesta). na.rm=TRUE
simplemente le dice a R que ignore a estos participantes para calcular el promedio.
La otra forma, que ya ocupamos más arriba, es con el comando with().
Esto es especialmente útil cuando queremos ocupar múltiples variables. El comando
insomnio = with(estudio2012,
data.frame(insom1, insom2, insom3, insom4, insom5))
crea una nueva base de datos -ocupando la función data.frame()- que sólo tiene la información de los ítems
de insomnio. Esto permite hacer análisis con la escala completa sin tener que volver a escribir cada variable.
describe(insomnio)
## vars n mean sd median trimmed mad min max range skew kurtosis
## insom1 1 111 3.44 2.03 3.0 3.30 2.97 1 7 6 0.46 -1.16
## insom2 2 111 3.27 2.00 3.0 3.10 2.97 1 7 6 0.49 -1.09
## insom3 3 110 3.10 2.00 2.5 2.93 2.22 1 7 6 0.48 -1.19

6
## insom4 4 110 4.08 2.20 4.0 4.10 2.97 1 7 6 0.04 -1.46
## insom5 5 110 3.88 2.27 4.0 3.85 2.97 1 7 6 0.08 -1.47
## se
## insom1 0.19
## insom2 0.19
## insom3 0.19
## insom4 0.21
## insom5 0.22
Otras funciones descriptivas son:
sd(estudio2012$insom1, na.rm=TRUE)
## [1] 2.035
median(estudio2012$insom1, na.rm=TRUE)
## [1] 3
y summary(), que es más o menos equivalente a describe() pero no requiere cargar una librería.
summary(insomnio)
## insom1 insom2 insom3 insom4 insom5
## Min. :1.00 Min. :1.00 Min. :1.0 Min. :1.00 Min. :1.00
## 1st Qu.:2.00 1st Qu.:2.00 1st Qu.:1.0 1st Qu.:2.00 1st Qu.:2.00
## Median :3.00 Median :3.00 Median :2.5 Median :4.00 Median :4.00
## Mean :3.44 Mean :3.27 Mean :3.1 Mean :4.08 Mean :3.88
## 3rd Qu.:5.00 3rd Qu.:5.00 3rd Qu.:5.0 3rd Qu.:6.00 3rd Qu.:6.00
## Max. :7.00 Max. :7.00 Max. :7.0 Max. :7.00 Max. :7.00
## NA's :1 NA's :1 NA's :2 NA's :2 NA's :2

Tablas y gráficos de frecuencia.

Además de indicadores descriptivos básicos como el promedio y la desviación estándar, muchas veces nos
interesa revisar la distribución de una variable. El ítem insom1 es un buen indicador general de insomnio:
“Generalmente me cuesta conciliar el sueño o despierto muchas veces en la noche”. A partir de los descriptivos,
describe(estudio2012$insom1)
## vars n mean sd median trimmed mad min max range skew kurtosis se
## X1 1 111 3.44 2.03 3 3.3 2.97 1 7 6 0.46 -1.16 0.19
podemos observar que los niveles de insomnio están aproximadamente en el punto medio de la escala (M
= 3.44), que hay una variación considerable entre los participantes (SD = 2.03), y que la distribución es
algo asimétrica: la mayoría de los participantes están a la izquierda de la distribución (Skew = .46). Esto es
visible también a partir de una simple tabla de frecuencia:
table(estudio2012$insom1)
##
## 1 2 3 4 5 6 7
## 22 24 21 10 7 15 12
En esta tabla, queda claro que hay una importante variación en el grado de acuerdo con este ítem, aunque
hay más personas en desacuerdo que de acuerdo. En vez de mirar un montón de números, podemos pedirle a
R que nos dibuje un gráfico. El comando
barplot(table(estudio2012$insom1))

7
20
15
10
5
0

1 2 3 4 5 6 7
dibuja un gráfico de barras con la información de la tabla que pedimos antes. Además de los datos para el
gráfico, podemos agregar un título y otras cosas.
Esto no es necesario si están revisando el gráfico para ustedes mismos, para tener una idea de cómo se
comportan los datos, pero sí es necesario cuando quieren mostrar estos resultados en un informe, artículo o
presentación.
Abajo vamos a pedir el mismo gráfico, pero agregando opciones para mejorar la presentación:
barplot(table(estudio2012$insom1), # datos del gráfico
main = "Insomnio en estudiantes", # título principal
xlab = "Grado de acuerdo", # etiqueta eje horizontal
ylab = "Frecuencia", # etiqueta eje vertical
col = "skyblue4" # cambio de color. ver colors()
)

8
Insomnio en estudiantes
20
15
Frecuencia

10
5
0

1 2 3 4 5 6 7

Grado de acuerdo
Estas opciones están disponibles, con la misma sintaxis, para todo tipo de gráficos. Si están ocupando
RStudio, pueden guardar el gráfico como imagen, pdf, o simplemente copiarlo en la memoria (para pegarlo
en Word, por ejemplo) seleccionando la opción correspondiente en el botón “Export”. Si presionan el botón
“Zoom”, el gráfico se abre en una nueva ventana, lo que puede ser útil para cambiar sus dimensiones. En ese
caso hay que hacer click derecho para copiarlo o exportarlo.
Cuando las variables son continuas, hacer una tabla de frecuencia es poco práctico y no entrega información
útil. Consideremos por ejemplo el promedio de todos los ítems de insomnio:
estudio2012$insom = with(insomnio,
(insom1 + insom2 + insom3 + insom4 + insom5)/5)
describe(estudio2012$insom)
## vars n mean sd median trimmed mad min max range skew kurtosis se
## X1 1 108 3.57 1.43 3.4 3.51 1.48 1 7 6 0.32 -0.67 0.14
Esta escala sigue siendo de 1 a 7, pero ahora tiene valores relativamente continuos. Por este motivo, hacer
una tabla de frecuencia es una mala idea:
table(estudio2012$insom)
##
## 1 1.4 1.6 1.8 2 2.2 2.4 2.6 2.8 3 3.2 3.4 3.6 3.8 4 4.2 4.4 4.6
## 1 6 4 4 5 4 4 4 9 3 4 9 1 8 5 5 3 3
## 4.8 5 5.2 5.4 5.8 6.2 6.4 6.6 6.8 7
## 1 7 8 2 1 2 1 2 1 1
barplot(table(estudio2012$insom))

9
8
6
4
2
0

1 1.6 2 2.4 3 3.4 4 4.4 5 5.4 6.4 7


La solución es hacer un histograma. Los histogramas grafican una tabla de intervalos, donde queremos saber
cuántas personas tienen puntajes entre 1 y 2, 2 y 3, etc. El comando es simplemente:
hist(estudio2012$insom)
Histogram of estudio2012$insom
25
20
Frequency

15
10
5
0

1 2 3 4 5 6 7

estudio2012$insom
Al igual que en los gráficos anteriores, podemos agregar opciones para mejorar la presentación.
hist(estudio2012$insom, # datos del gráfico
main = "Histograma escala de Insomnio", # título principal
xlab = "Grado de acuerdo", # etiqueta eje horizontal
ylab = "Frecuencia", # etiqueta eje vertical
col = "lightgray" # cambio de color

10
)
Histograma escala de Insomnio
25
20
Frecuencia

15
10
5
0

1 2 3 4 5 6 7

Grado de acuerdo
¿Por qué no ocupamos desde un comienzo hist() para hacer el gráfico de frecuencias? Los histogramas
están diseñados para variables continuas (por eso las barras están juntas), y desgraciadamente R se confunde
cuando le ponemos una variable discreta, como el primer item de la escala.
hist(estudio2012$insom1)

11
Histogram of estudio2012$insom1
40
30
Frequency

20
10
0

1 2 3 4 5 6 7

estudio2012$insom1
dibuja una situación muy distinta, y menos preocupante, que la situación real:
barplot(table(estudio2012$insom1))
20
15
10
5
0

1 2 3 4 5 6 7
De todas formas, esto es un error con la función hist(), que está sumando a las personas que marcan 1 y las
que marcan 2 en la primera barra. Espero que lo solucionen pronto. La función truehist() de la librería
MASS no tiene este problema.
# install.packages("MASS")
library(MASS)
truehist(estudio2012$insom1, col="lightgray")

12
0.20
0.15
0.10
0.05
0.00

1 2 3 4 5 6 7 8

estudio2012$insom1
En todo caso, lo que hay que recordar es que los histogramas son para variables continuas, no para variables
discretas.

Medidas de tendencia central

Podemos ocupar el mismo comando que ocupamos antes (barplot()) para hacer un gráfico con los promedios
de múltiples variables. Por ejemplo,
colMeans(insomnio, na.rm=TRUE) # imprime una tabla con los promedios de los ítems
## insom1 insom2 insom3 insom4 insom5
## 3.441 3.270 3.100 4.082 3.882
barplot(colMeans(insomnio, na.rm=TRUE)) # grafica esta tabla
4
3
2
1
0

insom1 insom2 insom3 insom4 insom5

13
Simplemente, la función barplot() saca los datos de una tabla de promedios en vez de una tabla de frecuencia.
Abajo les copio un comando para el mismo gráfico, pero con mejor presentación. Como ven, indentar y poner
comentarios es más útil cuando los comandos son más largos.
barplot(colMeans(insomnio, na.rm=TRUE),
main = "Promedios itemes escala insomnio", # título principal

ylab = "Grado de acuerdo", # etiqueta eje vertical

names = c("Item 1", "Item 2",


"Item 3", "Item 4", "Item 5"), # Nombres para las variables

col = rainbow(20, alpha = .6), # R incluye también paletas de color.


# pueden ejecutar help(rainbow)
# para más información

ylim = c(1,7), # la pregunta era de 1 a 7.


xpd = FALSE) # Es necesario para que las barras no comiencen en el
Promedios itemes escala insomnio
7
6
Grado de acuerdo

5
4
3
2
1

Item 1 Item 2 Item 3 Item 4 Item 5


Aunque estos gráficos son bastante típicos en informes, no es la mejor forma de mostrar el comportamiento de
estas variables. Literalmente, solo incluyen el promedio. Más adelante vamos a ver una función para agregar
al menos intervalos de confianza a este tipo de gráficos: error.bars() de la librería psych.
Una forma simple de mostrar más información (tendencia central, dispersión y simetría) es con un boxplot.
boxplot(insomnio)

14
7
6
5
4
3
2
1

insom1 insom2 insom3 insom4 insom5


Abajo lo copio con algunas opciones para mejorar la presentación.
boxplot(insomnio,
main="Insomnio en Estudiantes",
ylab="Grado de acuerdo",
names=c("Item 1", "Item 2", "Item 3", "Item 4", "Item 5"),
col=rainbow(5, alpha = .3)
)
Insomnio en Estudiantes
7
6
Grado de acuerdo

5
4
3
2
1

Item 1 Item 2 Item 3 Item 4 Item 5


Si no hubiéramos hecho la base de datos con los ítems de insomnio, el comando sería un poco más largo.
Abajo está hecho para los ítems de ansiedad ante las evaluaciones:
with(estudio2012,
boxplot(data.frame(ansev1, ansev2, ansev3, ansev4, ansev5),

15
main="Ansiedad ante evaluaciones",
names=c("Dif. dormir", "Despertar",
"Irritable", "Dolores", "No desconectar"),
col=rainbow(5, alpha = .3),
las = 2, cex.axis=.7)
)
Ansiedad ante evaluaciones

1
Dif. dormir

Despertar

Irritable

Dolores

No desconectar

Esta vez agregué las = 2, cex.axis=.7 porque las etiquetas para los ítemes son más largas, también pueden
abrir el gráfico en una nueva ventana para verlos bien (presionando Zoom) y exportar esa imagen.

Comparando distintos grupos.

La base de datos alumnos2012.csv incluye una serie de variables que identifican distintos grupos a los que
pertenecen las personas. Por ejemplo, si son hombres o mujeres, o su situación sentimental.
table(estudio2012$genero)
##
## Femenino Masculino
## 3 82 27
table(estudio2012$sitsent)
##
## En una relacion Es complicado Soltero/a
## 1 54 8 49
Estas variables están codificadas como texto, y en los casos en que alguien no contestó estas preguntas (3
personas no indicaron su género y 1 persona no indicó su situación sentimental) los datos tienen simplemente
una celda vacía.

16
Todo esto significa que tenemos que hacer algo de trabajo antes de poder ocupar estas variables para nuestros
análisis. Por ejemplo, si hacemos un gráfico de barras para situación sentimental,
barplot(table(estudio2012$sitsent))
50
40
30
20
10
0

En una relacion Es complicado Soltero/a


Vemos que hay una barra extra con la persona que prefirió no contestar esta pregunta.
Las variables categóricas son importantes y las vamos a ocupar para una serie de análisis, por lo que vale la
pena hacer un procesamiento preliminar de los datos.
El siguiente comando crea una nueva variable -sitsentf- en la base de datos estudio2012 donde se seleccionan
solamente los grupos que nos interesan.
estudio2012$sitsentf = factor(estudio2012$sitsent,

# Esto crea una variable nueva a partir de sitsent,


# considerándola como un factor (una variable categórica)
# por eso le puse el nombre sitsentf

levels=c("En una relacion",


"Es complicado", "Soltero/a")

# Esto selecciona los niveles que nos interesan,


# es decir, sin incluir las personas que no contestaron.
)
El comando
estudio2012$sitsentf
## [1] En una relacion En una relacion Soltero/a Soltero/a
## [5] Soltero/a Soltero/a Es complicado Soltero/a
## [9] Soltero/a En una relacion Soltero/a En una relacion
## [13] En una relacion Soltero/a En una relacion En una relacion
## [17] Soltero/a En una relacion En una relacion Soltero/a
## [21] Es complicado Soltero/a Soltero/a Soltero/a
## [25] En una relacion En una relacion Es complicado En una relacion
## [29] En una relacion En una relacion En una relacion Soltero/a

17
## [33] Es complicado Soltero/a En una relacion En una relacion
## [37] En una relacion Soltero/a En una relacion En una relacion
## [41] En una relacion Soltero/a Es complicado Es complicado
## [45] Soltero/a Soltero/a Es complicado En una relacion
## [49] Soltero/a Soltero/a Soltero/a <NA>
## [53] Soltero/a Soltero/a Soltero/a Soltero/a
## [57] En una relacion En una relacion Soltero/a Soltero/a
## [61] En una relacion En una relacion En una relacion Soltero/a
## [65] En una relacion Soltero/a Soltero/a En una relacion
## [69] Soltero/a En una relacion Soltero/a En una relacion
## [73] Soltero/a Soltero/a En una relacion En una relacion
## [77] Soltero/a En una relacion En una relacion Soltero/a
## [81] En una relacion En una relacion En una relacion Soltero/a
## [85] En una relacion En una relacion Soltero/a En una relacion
## [89] En una relacion Soltero/a En una relacion Soltero/a
## [93] En una relacion Soltero/a En una relacion En una relacion
## [97] En una relacion En una relacion Soltero/a En una relacion
## [101] Soltero/a En una relacion Es complicado Soltero/a
## [105] En una relacion Soltero/a En una relacion Soltero/a
## [109] En una relacion Soltero/a Soltero/a En una relacion
## Levels: En una relacion Es complicado Soltero/a
imprime todos los datos de esta variable en la consola, y el participante 52 ahora tiene en vez de una celda
vacía.
estudio2012[52,]$sitsentf # muestra la situación sentimental del participante 52 (NA)
## [1] <NA>
## Levels: En una relacion Es complicado Soltero/a
Cuando pedimos la tabla, ahora ya no incluye a este participante:
table(estudio2012$sitsentf)
##
## En una relacion Es complicado Soltero/a
## 54 8 49
barplot(table(estudio2012$sitsentf))

18
50
40
30
20
10
0

En una relacion Es complicado Soltero/a


La base de datos,
names(estudio2012)
## [1] "n" "sitsent" "desconf1" "desconf2" "desconf3" "desconf4"
## [7] "desconf5" "vidau1" "vidau2" "vidau3" "vidau4" "vidau5"
## [13] "starb1" "starb2" "starb3" "starb4" "starb5" "ayude1"
## [19] "ayude2" "ayude3" "ayude4" "ayude5" "abor1" "abor2"
## [25] "abor3" "abor4" "abor5" "tolsex1" "tolsex2" "tolsex3"
## [31] "tolsex4" "tolsex5" "intex1" "intex2" "intex3" "intex4"
## [37] "intex5" "acogex1" "acogex2" "acogex3" "acogex4" "acogex5"
## [43] "ansev1" "ansev2" "ansev3" "ansev4" "ansev5" "insom1"
## [49] "insom2" "insom3" "insom4" "insom5" "intui1" "intui2"
## [55] "intui3" "intui4" "intui5" "valma1" "valma2" "valma3"
## [61] "valma4" "valma5" "streu1" "streu2" "streu3" "streu4"
## [67] "streu5" "intay1" "intay2" "intay3" "intay4" "intay5"
## [73] "tprej1" "tprej2" "tprej3" "tprej4" "tprej5" "genero"
## [79] "zodiaco" "orienpol" "mencion" "votop" "herman" "lugar"
## [85] "insom" "sitsentf"
ahora incluye al final una nueva variable sitsentf. Esta variable está en la base de datos estudio2012 que
tenemos en nuestro espacio de trabajo. No en el archivo alumnos2012.csv.
Vamos a hacer el mismo procesamiento con género
table(estudio2012$genero)
##
## Femenino Masculino
## 3 82 27
estudio2012$generof = factor(estudio2012$genero,
levels=c("Femenino","Masculino"),
labels=c("Mujer","Hombre"))
# con "labels" podemos cambiar los nombres de las
# categorías

table(estudio2012$generof)

19
##
## Mujer Hombre
## 82 27
y con orientación política
table(estudio2012$orienpol)
##
## Centro Centro Derecha Centro Izquierda
## 2 8 18 20
## Derecha Independiente Izquierda Ninguna
## 19 8 18 19
estudio2012$orienpolf = factor(estudio2012$orienpol,

# Al seleccionar los niveles, podemos hacer varias cosas


# con esta variable: ordenarlos de izquierda a derecha,
# omitir los independientes y los que dicen "ninguna",
# y omitir a los que no contestaron. Todos estos van a
# quedar como NA. (por supuesto, para otros análisis
# podríamos querer mantener a los independientes y a los
# que no se identifican)

levels=c("Izquierda","Centro Izquierda","Centro",
"Centro Derecha","Derecha"))

table(estudio2012$orienpolf)
##
## Izquierda Centro Izquierda Centro Centro Derecha
## 18 20 8 18
## Derecha
## 19

Descripción de la muestra.

Una de las cosas más simples que podemos querer hacer con este tipo de variables es describir la cantidad de
personas que pertenecen a cada grupo, por ejemplo a través de gráficos de barra
barplot(table(estudio2012$orienpolf),
col=rainbow(30, alpha=.6))

20
20
15
10
5
0

Izquierda Centro Centro Derecha


Si quieren hacer un gráfico de torta, el comando es pie()
pie(table(estudio2012$sitsentf),
main="Situacion sentimental estudiantes 2012",
col=terrain.colors(5, alpha = .6),
radius = .8)
Situacion sentimental estudiantes 2012

En una relacion

Es complicado

Soltero/a
También es común querer cruzar dos tablas de frecuencia (crosstabs), lo que se hace simplemente agregando
otra variable al comando table():
table(estudio2012$sitsentf,estudio2012$generof)
##
## Mujer Hombre
## En una relacion 44 9
## Es complicado 4 4
## Soltero/a 33 14

21
Si prefieren reportar los porcentajes o proporciones. La función prop.table() hace esta transformación a
partir de los resultados de table():
Esta vez vamos a asignar esta tabla a un objeto para simplificar los comandos siguientes. Como es un objeto
temporal, le vamos a poner “x”. Si tuviera un uso más permanente sería mejor ponerle un nombre más
descriptivo.
x = table(estudio2012$sitsentf,estudio2012$generof) # asigna la tabla al objeto "x"

prop.table(x) # proporciones por celda


##
## Mujer Hombre
## En una relacion 0.40741 0.08333
## Es complicado 0.03704 0.03704
## Soltero/a 0.30556 0.12963
prop.table(x, 1) # proporciones por fila
##
## Mujer Hombre
## En una relacion 0.8302 0.1698
## Es complicado 0.5000 0.5000
## Soltero/a 0.7021 0.2979
prop.table(x, 2) # proporciones por columna
##
## Mujer Hombre
## En una relacion 0.54321 0.33333
## Es complicado 0.04938 0.14815
## Soltero/a 0.40741 0.51852
¿Cómo podemos graficar esto? Una buena opción es ocupar nuevamente un gráfico de barras.
barplot(table(estudio2012$sitsentf, estudio2012$generof),
legend=TRUE, # agrega automáticamente una leyenda
col=heat.colors(3, alpha=.6)
)
80

Soltero/a
Es complicado
60

En una relacion
40
20
0

Mujer Hombre

22
Para hacer que cada grupo tenga una barra, hay que ocupar el argumento beside.
barplot(table(estudio2012$sitsentf, estudio2012$generof),
legend=TRUE,
col=heat.colors(3, alpha=.6),
beside=TRUE # esta opción hace que cada grupo tenga una barra
)
40

En una relacion
Es complicado
Soltero/a
30
20
10
0

Mujer Hombre
Por último, es común querer comparar los grupos en una o más variables continuas, como querer ver los
niveles de insomnio separado por hombres y mujeres. En un boxplot, podemos ocupar el signo ~ para indicar
que se quiere separar por grupos.
En general, ~ significa “predicho por” en R. (En mi computador, tengo que presionar alt+ñ para escribir este
signo, pero eso va a depender de la configuración de su teclado).
boxplot(insom1~sitsentf, data=estudio2012,
main="Problemas de insomnio en relaciones complicadas",
ylab="Insomnio",
col=heat.colors(3,alpha=.6))

23
Problemas de insomnio en relaciones complicadas
7
6
5
Insomnio

4
3
2
1

En una relacion Es complicado Soltero/a


Aunque creo comparar grupos a partir de boxplots es mejor, también pueden hacer un gráfico de barras con
los promedios. La función tapply() es ideal para obtener los promedios de distintos grupos.
El formato de esta función es poner primero la variable dependiente, después el factor que define los grupos
y después la función que se quiere ocupar. El resultado de tapply() puede ser entregado directamente a
barplot().
tapply(estudio2012$insom1, estudio2012$sitsentf, mean, na.rm=TRUE)
## En una relacion Es complicado Soltero/a
## 3.278 4.375 3.438
barplot(tapply(estudio2012$insom1, estudio2012$sitsentf, mean, na.rm=TRUE))
4
3
2
1
0

En una relacion Es complicado Soltero/a


Finalmente, la función tapply() también permite ocupar dos o más factores para definir los grupos. Todo lo

24
que hay que hacer es ocupar el comando list() para hacer una lista con los factores a ocupar. El comando de
abajo hace una tabla con los promedios de insomnio según situación sentimental, separando además hombres
de mujeres.
tapply(estudio2012$insom1,
list(estudio2012$sitsentf, estudio2012$generof), mean, na.rm=TRUE)
## Mujer Hombre
## En una relacion 3.068 3.889
## Es complicado 5.000 3.750
## Soltero/a 3.515 3.000
Especialmente al reportar experimentos, es común hacer un gráfico de líneas para reportar interacciones entre
dos factores. R tiene un comando para esto, interaction.plot(factor eje x, factor con diferentes líneas, variable
dependiente).
with(estudio2012,
interaction.plot(generof, sitsentf, insom1))
5.0

sitsentf
En una relacion
4.5

Es complicado
mean of insom1

Soltero/a
4.0
3.5
3.0

Mujer Hombre

generof
Nuevamente, podemos mejorar la presentación del gráfico agregando más parámetros:
with(estudio2012,
interaction.plot(generof, sitsentf, insom1,
ylim=c(1,7),
lty = 1,
col=c("red","blue","darkgreen"),
main="Insomnio segun genero y situacion sentimental",
ylab="Insomnio",
xlab=""))

25
Insomnio segun genero y situacion sentimental
7
sitsentf
6

En una relacion
Es complicado
5

Soltero/a
Insomnio

4
3
2
1

Mujer Hombre
Desgraciadamente esta función no reacciona bien a NAs en la variable dependiente. Por ejemplo, el cuarto
ítem de desconfianza en la pareja, “Si mi pareja reacciona de manera fría, tiendo a pensar que tiene un
problema conmigo” tiene 3 personas que no contestaron.
summary(estudio2012$desconf4) # ver NA's
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 1.00 4.00 5.00 4.61 6.00 7.00 3
Si hacemos el gráfico tal como lo hicimos antes, nos van a faltar varias líneas
with(estudio2012,
interaction.plot(generof, sitsentf, desconf4,
ylim=c(1,7)))

26
7
sitsentf
6 Es complicado
mean of desconf4

En una relacion
5

Soltero/a
4
3
2
1

Mujer Hombre

generof
La solución es explicitar que la fórmula para el promedio tiene que ignorar los datos perdidos,
with(estudio2012,
interaction.plot(generof, sitsentf, desconf4,

# agregando el siguiente argumento:


fun=function(x) mean(x, na.rm=TRUE)))
function(x) mean(x, na.rm = TRUE) of desconf4

6.0

sitsentf
Es complicado
Soltero/a
5.5

En una relacion
5.0
4.5

Mujer Hombre

generof
Pareciera que los hombres, pero no las mujeres, tienden a tener mayor desconfianza o inseguridad en relaciones

27
complicadas (recuerden que hay solo 4 participantes hombres que reportan su situación sentimental como
complicada, ¡no se tomen muy en serio estos resultados!)
table(estudio2012$sitsentf, estudio2012$generof)
##
## Mujer Hombre
## En una relacion 44 9
## Es complicado 4 4
## Soltero/a 33 14

Relaciones entre variables continuas.

Es tremendamente común el psicología querer relacionar distintas variables continuas a partir de disper-
siogramas, como ya hicimos al comienzo de este tutorial con los niveles de extraversión y de apertura a la
experiencia. Revisemos la relación entre insomnio y ansiedad en periodo de evaluaciones.
Primero tenemos que calcular el promedio de la escala. Dado que vamos a relacionarla con los niveles de
insomnio, prefiero no ocupar los ítems que se refieren a problemas de dormir en periodos de evaluaciones.
estudio2012$ansev = with(estudio2012,
(ansev3+ansev4+ansev5)/3)

estudio2012$insom = with(estudio2012,
(insom1+insom2+insom3+insom4+insom5)/3,
na.rm=TRUE)
Ahora podemos pedir un dispersiograma
with(estudio2012, plot(ansev, insom))
12
10
8
insom

6
4
2

1 2 3 4 5 6 7

ansev
plot(estudio2012$ansev, estudio2012$insom,
main="Relacion entre ansiedad ante evaluaciones e insomnio",
col="cadetblue4",
xlab="Ansiedad ante evaluaciones",

28
ylab="Insomnio"
)
12
10
8 Relacion entre ansiedad ante evaluaciones e insomnio
Insomnio

6
4
2

1 2 3 4 5 6 7

Ansiedad ante evaluaciones


Como se observa en el gráfico, hay una correlación positiva entre las dos variables. Quienes reportan más
ansiedad en periodos de evaluaciones reportan también mayores niveles de insomnio.
Para obtener el coeficiente de correlación entre estas variables pueden ocupar la función cor().
cor(estudio2012$ansev, estudio2012$insom,
use = "pairwise.complete.obs" # necesario cuando hay NAs
)
## [1] 0.3182
Este tipo de gráficos permite además agregar más información. Por ejemplo, poner una línea que indica la
relación lineal entre las variables:
plot(estudio2012$ansev, estudio2012$insom,
main="Relacion entre ansiedad ante evaluaciones e insomnio",
col="cadetblue4",
xlab="Ansiedad ante evaluaciones",
ylab="Insomnio"
)

abline(lm(estudio2012$insom~estudio2012$ansev),
col="firebrick")

29
Relacion entre ansiedad ante evaluaciones e insomnio
12
10
8
Insomnio

6
4
2

1 2 3 4 5 6 7

Ansiedad ante evaluaciones


Para hacer esto más complicado, la función lm() ocupa un orden distinto para las variables x e y. El comando
plot tiene el formato (x, y), mientras que el comando lm() tiene el formato y~x (y predicho por x).
Otra opción es dibujar una linea que se ajuste a los datos, pero no forzar que sea una linea recta. supsmu()
es una buena función para hacer esto.
plot(estudio2012$ansev, estudio2012$insom,
main="Relacion entre ansiedad ante evaluaciones e insomnio",
col="cadetblue4",
xlab="Ansiedad ante evaluaciones",
ylab="Insomnio"
)

abline(lm(estudio2012$insom~estudio2012$ansev),
col="firebrick")

lines(supsmu(estudio2012$ansev, estudio2012$insom,
bass=2), # de 0 a 10, controla el nivel de "smoothness" de la linea
col="royalblue1")

30
Relacion entre ansiedad ante evaluaciones e insomnio
12
10
8
Insomnio

6
4
2

1 2 3 4 5 6 7

Ansiedad ante evaluaciones


A veces nos interesa revisar la relación de dos variables continuas, pero separando por distintos grupos. Una
forma simple de hacer esto es con la librería lattice.
# install.packages("lattice") # Una vez que ya lo tienen instalado no es necesario
# ejecutar nuevamente este comando.

library(lattice)
La función xyplot() de lattice funciona con la misma sintaxis que lm(): y~x, pero además permite separar
por grupos ocupando el signo | (en mi computador, esto es alt+1).
xyplot(insom~ansev|generof, estudio2012)

31
1 2 3 4 5 6 7

Mujer Hombre
12

10

8
insom

1 2 3 4 5 6 7

ansev
La librería lattice tiene una gran cantidad de comandos para hacer gráficos, que pueden explorar libremente.
En general opté por ocupar librerías solamente cuando facilita substancialmente las cosas. Ahora vamos a ver
una opción para visualizar estos datos sin ocupar lattice.
En vez de hacer gráficos por separado, podemos hacer que los círculos en el dispersiograma tengan un color
distinto en base al grupo al que pertenece la persona.
Hacer el gráfico por separado para hombres y mujeres es más que suficiente, pero al explicar cómo incluir
ambos en el mismo gráfico vamos a aprovechar de explicar algunas funciones más fundamentales de R y
ejemplificar cómo podemos usar las funciones de forma creativa para llegar al resultado que queremos.
Primero tenemos que hacer un objeto con los colores que vamos a ocupar:
colores = c("red","blue")
Esto simplemente crea un objeto con una lista de dos colores. La función c(), que ya habíamos ocupado más
arriba sin explicar, simplemente concatena los elementos para que queden en una lista.
colores
## [1] "red" "blue"
En vez de ocupar rainbow() o repetir los colores que se van a ocupar en cada gráfico, cuando están haciendo
un informe puede ser útil hacer una paleta de colores personalizada ocupando esta función. Esto permite
además cambiar los colores de todos los gráficos sin tener que modificar cada uno de los comandos. Basta
reemplazar los colores en el objeto que crearon.
Lo que tenemos ahora es una lista en que el elemento 1 es “red” y el elemento 2 es “blue”. Los factores (las
variables categóricas) también están codificados como una lista. La función
levels(estudio2012$generof)
## [1] "Mujer" "Hombre"

32
muestra los valores que puede tener la variable generof. El primer elemento es “Mujer”, y el segundo elemento
es “Hombre”.
La gracia es que ahora podemos reemplazar “Mujer” y “Hombre” por “red” o “blue” tal como aparecen en el
objeto “colores”:
colores[estudio2012$generof] # obtiene los datos de "generof", ocupando los elementos del objeto "colore
## [1] "red" "red" "red" "red" "red" "red" "blue" "blue" "red" "red"
## [11] "blue" NA "red" "blue" "red" "red" "blue" "red" "blue" "red"
## [21] "blue" "red" "red" "red" "red" "red" "red" "red" "red" "red"
## [31] "red" "red" "red" "blue" "red" "red" "red" "blue" "red" "blue"
## [41] "red" "red" "blue" "red" "blue" "red" "blue" "blue" "red" "red"
## [51] "red" "red" "red" NA "blue" "red" "red" "red" "red" "blue"
## [61] "red" "red" "red" "blue" "blue" "red" "red" "red" "blue" "red"
## [71] "red" "red" "red" "red" "red" "red" "blue" "red" "blue" "blue"
## [81] "blue" "red" "red" "red" "red" "red" "red" "blue" "red" "red"
## [91] "red" "blue" "red" "red" "red" "blue" "red" "red" "red" "red"
## [101] "red" "blue" "red" NA "red" "red" "red" "red" "red" "red"
## [111] "red" "red"
Si les parece raro, no se preocupen, no importa por qué funciona. Lo que importa es que podemos hacer el
siguiente gráfico de dispersión:
plot(estudio2012$ansev, estudio2012$insom,
main="Relacion entre ansiedad ante evaluaciones e insomnio",

col=colores[estudio2012$generof], # Magia

xlab="Ansiedad ante evaluaciones",


ylab="Insomnio"
)
Relacion entre ansiedad ante evaluaciones e insomnio
12
10
8
Insomnio

6
4
2

1 2 3 4 5 6 7

Ansiedad ante evaluaciones

33
También podemos agregar una leyenda con los colores:
plot(estudio2012$ansev, estudio2012$insom,
main="Relacion entre ansiedad ante evaluaciones e insomnio",

col=colores[estudio2012$generof], # Magia

xlab="Ansiedad ante evaluaciones",


ylab="Insomnio"
)

legend("topleft", # Ubicación de la leyenda


levels(estudio2012$generof), # Texto de la leyenda.
# Podríamos haber escrito c("Mujer","Hombre")
col = colores, # Los colores asociados con el texto
pch = 19 # El símbolo a ocupar en la leyenda
)
Relacion entre ansiedad ante evaluaciones e insomnio
12

Mujer
Hombre
10
8
Insomnio

6
4
2

1 2 3 4 5 6 7

Ansiedad ante evaluaciones


También podemos incluir una línea para cada grupo. Esto requiere ocupar solamente a los participantes
hombres o mujeres según corresponda.
Al comienzo de este tutorial, vimos los datos del participante 52 con el comando
estudio2012[52,]
En este caso, lo que está entre corchetes es un subgrupo de la base de datos, con la forma: datos[filas,
columnas]. Si quisiéramos ver los datos de la segunda columna (la situación sentimental), podemos ejecutar
estudio2012[,2]
## [1] En una relacion En una relacion Soltero/a Soltero/a
## [5] Soltero/a Soltero/a Es complicado Soltero/a
## [9] Soltero/a En una relacion Soltero/a En una relacion

34
## [13] En una relacion Soltero/a En una relacion En una relacion
## [17] Soltero/a En una relacion En una relacion Soltero/a
## [21] Es complicado Soltero/a Soltero/a Soltero/a
## [25] En una relacion En una relacion Es complicado En una relacion
## [29] En una relacion En una relacion En una relacion Soltero/a
## [33] Es complicado Soltero/a En una relacion En una relacion
## [37] En una relacion Soltero/a En una relacion En una relacion
## [41] En una relacion Soltero/a Es complicado Es complicado
## [45] Soltero/a Soltero/a Es complicado En una relacion
## [49] Soltero/a Soltero/a Soltero/a
## [53] Soltero/a Soltero/a Soltero/a Soltero/a
## [57] En una relacion En una relacion Soltero/a Soltero/a
## [61] En una relacion En una relacion En una relacion Soltero/a
## [65] En una relacion Soltero/a Soltero/a En una relacion
## [69] Soltero/a En una relacion Soltero/a En una relacion
## [73] Soltero/a Soltero/a En una relacion En una relacion
## [77] Soltero/a En una relacion En una relacion Soltero/a
## [81] En una relacion En una relacion En una relacion Soltero/a
## [85] En una relacion En una relacion Soltero/a En una relacion
## [89] En una relacion Soltero/a En una relacion Soltero/a
## [93] En una relacion Soltero/a En una relacion En una relacion
## [97] En una relacion En una relacion Soltero/a En una relacion
## [101] Soltero/a En una relacion Es complicado Soltero/a
## [105] En una relacion Soltero/a En una relacion Soltero/a
## [109] En una relacion Soltero/a Soltero/a En una relacion
## Levels: En una relacion Es complicado Soltero/a
Noten que ahora el número está después de la coma, porque se refiere a una columna. Si quisiéramos saber la
situación sentimental del participante 86, tenemos que ejecutar
estudio2012[86,2]
## [1] En una relacion
## Levels: En una relacion Es complicado Soltero/a
Pero los números de fila y columna también pueden ser expresiones lógicas, lo que nos permite seleccionar
parte de la base de datos según alguna condición, por ejemplo que los participantes sean hombres:
estudio2012[estudio2012$generof=="Hombre",]
Noten que la condición está puesta antes de la coma, queremos seleccionar las filas donde el valor de generof
es “Masculino”.
El uso de “==” también es importante. Esto es para distinguirlo de “=”, que se ocupa para asignar el
resultado de una función a un objeto.
Para dibujar las líneas que mejor se ajustan a los datos de mujeres y hombres, podemos correr el mismo
comando de antes, abline(), pero ocupando un subset de la base de datos:
plot(estudio2012$ansev, estudio2012$insom,
main="Relacion entre ansiedad ante evaluaciones e insomnio",

col=colores[estudio2012$generof], # Magia

xlab="Ansiedad ante evaluaciones",


ylab="Insomnio"
)

35
legend("topleft", # Ubicación de la leyenda
levels(estudio2012$generof), # Texto de la leyenda.
# Podríamos haber escrito c("Mujer","Hombre")
col = colores, # Los colores asociados con el texto
pch = 19 # El símbolo a ocupar en la leyenda
)

with(estudio2012[estudio2012$generof=="Mujer", ], # Selecciona únicamente a las mujeres


abline(lm(insom~ansev), col=colores[1])) # Selecciona el primer color de la lista

with(estudio2012[estudio2012$generof=="Hombre", ], # Selecciona únicamente a los hombres


abline(lm(insom~ansev), col=colores[2])) # Selecciona el segundo color de la lista
Relacion entre ansiedad ante evaluaciones e insomnio
12

Mujer
Hombre
10
8
Insomnio

6
4
2

1 2 3 4 5 6 7

Ansiedad ante evaluaciones

Matriz de correlaciones.

Para terminar con el tema de los gráficos y de la exploración de datos, queda por mencionar que la función
plot() también puede graficar las correlaciones entre múltiples variables. Por ejemplo, podemos ver las
correlaciones entre los cinco factores de personalidad del “big five” en la base de datos que viene con la
librería psych.
En caso de que no la tengan cargada:
library(psych)
personalidad = epi.bfi
La función plot hace automáticamente la matriz de dispersiogramas si le entregan más de dos variables. Para
simplificar los comandos, vamos a crear una nueva base de datos solamente con los factores del big-five.
bf = with(personalidad,
data.frame(bfagree, bfcon, bfext, bfneur, bfopen))

36
plot(bf)
60 100 140 180 40 80 120

140
bfagree

80
60 120

bfcon

150
bfext

50
40 100

bfneur

140
bfopen

80
80 120 160 50 100 80 120 160

Si quieren ver la tabla de correlaciones en la consola, pueden ejecutar:


cor(bf)
## bfagree bfcon bfext bfneur bfopen
## bfagree 1.00000 0.4499 0.47848 -0.04462 0.3942
## bfcon 0.44990 1.0000 0.26675 0.04450 0.3052
## bfext 0.47848 0.2668 1.00000 0.03713 0.4588
## bfneur -0.04462 0.0445 0.03713 1.00000 0.2935
## bfopen 0.39415 0.3052 0.45876 0.29348 1.0000
La función round() permite quitar decimales a ésta o cualquier otra tabla.
round(cor(bf), 2)
## bfagree bfcon bfext bfneur bfopen
## bfagree 1.00 0.45 0.48 -0.04 0.39
## bfcon 0.45 1.00 0.27 0.04 0.31
## bfext 0.48 0.27 1.00 0.04 0.46
## bfneur -0.04 0.04 0.04 1.00 0.29
## bfopen 0.39 0.31 0.46 0.29 1.00
La librería psych también tiene funciones gráficas para esto, con algunas opciones extra. En mi opinión
estos gráficos son horribles, pero son útiles para explorar rápidamente las variables. Por defecto, la función
pairs.panels() entrega dispersiogramas con una línea de ajuste, histogramas para ver la distribución de las
variables, y además los coeficientes de correlación.
pairs.panels(bf)

37
60 100 140 180 40 80 120

bfagree

140
0.45 0.48 −0.04 0.39

80
bfcon
0.27 0.04 0.31
60 120

150
bfext
0.04 0.46

50
bfneur
0.29
40 100

bfopen

140
80
80 120 160 50 100 80 120 160

Obviamente, este tipo de gráficos pierde sentido a medida que aumenta el número de variables. Ejecutar
plot(personalidad)
0 8 0 5 80 50 80 30 70

epiE

5
epiS
0

epiImp

0
epilie
0

epiNeur 0

bfagree
80

bfcon
60
50

bfext

bfneur
40

bfopen
80

bdi
0

traitanx
30

stateanx
20

5 20 0 6 0 20 60 180 40 0 20 20 70

es poco práctico. Pero la librería psych incluye un gráfico que es perfecto para esto, y que no es horrible:
cor.plot(). Este gráfico pone distintos colores dependiendo de qué tan fuerte es la correlación entre dos
variables. A diferencia de plot() o de pairs.panels(), cor.plot() requiere los datos de una tabla de
correlaciones.

38
round(cor(personalidad), 2)
## epiE epiS epiImp epilie epiNeur bfagree bfcon bfext bfneur
## epiE 1.00 0.85 0.80 -0.22 -0.18 0.18 -0.11 0.54 -0.09
## epiS 0.85 1.00 0.43 -0.05 -0.22 0.20 0.05 0.58 -0.07
## epiImp 0.80 0.43 1.00 -0.24 -0.07 0.08 -0.24 0.35 -0.09
## epilie -0.22 -0.05 -0.24 1.00 -0.25 0.17 0.23 -0.04 -0.22
## epiNeur -0.18 -0.22 -0.07 -0.25 1.00 -0.08 -0.13 -0.17 0.63
## bfagree 0.18 0.20 0.08 0.17 -0.08 1.00 0.45 0.48 -0.04
## bfcon -0.11 0.05 -0.24 0.23 -0.13 0.45 1.00 0.27 0.04
## bfext 0.54 0.58 0.35 -0.04 -0.17 0.48 0.27 1.00 0.04
## bfneur -0.09 -0.07 -0.09 -0.22 0.63 -0.04 0.04 0.04 1.00
## bfopen 0.14 0.15 0.07 -0.03 0.09 0.39 0.31 0.46 0.29
## bdi -0.16 -0.13 -0.11 -0.20 0.58 -0.14 -0.18 -0.14 0.47
## traitanx -0.23 -0.26 -0.12 -0.23 0.73 -0.31 -0.29 -0.39 0.59
## stateanx -0.13 -0.12 -0.09 -0.15 0.49 -0.19 -0.14 -0.15 0.49
## bfopen bdi traitanx stateanx
## epiE 0.14 -0.16 -0.23 -0.13
## epiS 0.15 -0.13 -0.26 -0.12
## epiImp 0.07 -0.11 -0.12 -0.09
## epilie -0.03 -0.20 -0.23 -0.15
## epiNeur 0.09 0.58 0.73 0.49
## bfagree 0.39 -0.14 -0.31 -0.19
## bfcon 0.31 -0.18 -0.29 -0.14
## bfext 0.46 -0.14 -0.39 -0.15
## bfneur 0.29 0.47 0.59 0.49
## bfopen 1.00 -0.08 -0.11 -0.04
## bdi -0.08 1.00 0.65 0.61
## traitanx -0.11 0.65 1.00 0.57
## stateanx -0.04 0.61 0.57 1.00
cor.plot(cor(personalidad))

Correlation plot

epiE 1
epiS 0.8
epiImp
0.6
epilie
epiNeur 0.4
bfagree 0.2
bfcon
bfext 0
bfneur −0.2
bfopen
−0.4
bdi
traitanx −0.6
stateanx −0.8
−1
epiE

epiS

epiImp

epilie

epiNeur

bfagree

bfcon

bfext

bfneur

bfopen

bdi

traitanx

stateanx

39
Como ven, el gráfico permite identificar de manera rápida cuáles son las variables que correlacionan entre si.

Cálculo de escalas y psicometría.


El gráfico de correlaciones que entrega cor.plot() es una excelente introducción al tema de la psicometría y
cómo calcular escalas. Al medir constructos psicológicos es preferible ocupar múltiples ítems ya que cada
uno de ellos es un indicador imperfecto de los niveles del constructo. Pero si los ítems efectivamente están
midiendo el mismo constructo, uno esperaría que la correlación entre ellos sea alta. Por ejemplo, veamos la
correlación entre los ítems de insomnio:
x = cor(insomnio, # Vamos a asignar las correlaciones a un objeto, x
use = "pairwise.complete.obs") # necesario cuando hay NAs

round(x, 2) # Imprime la tabla de correlaciones en la consola


## insom1 insom2 insom3 insom4 insom5
## insom1 1.00 0.90 0.37 0.37 0.30
## insom2 0.90 1.00 0.35 0.35 0.31
## insom3 0.37 0.35 1.00 0.09 0.05
## insom4 0.37 0.35 0.09 1.00 0.56
## insom5 0.30 0.31 0.05 0.56 1.00
cor.plot(x) # Grafica la tabla de correlaciones

Correlation plot

1
insom1 0.8
0.6
insom2 0.4
0.2
insom3
0
−0.2
insom4
−0.4
−0.6
insom5
−0.8
−1
insom1

insom2

insom3

insom4

insom5

Claramente, los ítems 1 y 2 correlacionan muy fuertemente entre si (r = .90), y bastante bien con el resto. El
ítem 3 correlaciona algo con el 1 y 2, pero no correlaciona con los ítems 4 y 5, que si correlacionan entre si.
Hay dos formas principales de simplificar toda esta información para poder decidir si estos ítems son una
medición confiable de los niveles de insomnio, o si están midiendo más de un constructo.
La primera, y la más simple, es analizar la confiabilidad de la escala por medio del alpha de Cronbach. La
librería psych tiene un comando para hacer esto.

40
alpha(insomnio) # Probablemente tienen que moverse en la consola para ver el output completo de este aná
##
## Reliability analysis
## Call: alpha(x = insomnio)
##
## raw_alpha std.alpha G6(smc) average_r S/N ase mean sd
## 0.74 0.74 0.79 0.36 2.8 0.04 3.6 1.5
##
## lower alpha upper 95% confidence boundaries
## 0.66 0.74 0.82
##
## Reliability if an item is dropped:
## raw_alpha std.alpha G6(smc) average_r S/N alpha se
## insom1 0.61 0.61 0.60 0.28 1.6 0.060
## insom2 0.62 0.62 0.61 0.29 1.6 0.059
## insom3 0.77 0.78 0.82 0.46 3.4 0.038
## insom4 0.70 0.71 0.75 0.38 2.4 0.048
## insom5 0.73 0.73 0.76 0.40 2.7 0.043
##
## Item statistics
## n raw.r std.r r.cor r.drop mean sd
## insom1 111 0.82 0.84 0.88 0.70 3.4 2.0
## insom2 111 0.82 0.83 0.87 0.69 3.3 2.0
## insom3 110 0.52 0.53 0.32 0.27 3.1 2.0
## insom4 110 0.70 0.67 0.55 0.48 4.1 2.2
## insom5 110 0.66 0.63 0.49 0.42 3.9 2.3
##
## Non missing response frequency for each item
## 1 2 3 4 5 6 7 miss
## insom1 0.20 0.22 0.19 0.09 0.06 0.14 0.11 0.01
## insom2 0.24 0.22 0.14 0.09 0.13 0.09 0.09 0.01
## insom3 0.32 0.18 0.11 0.09 0.13 0.12 0.05 0.02
## insom4 0.15 0.17 0.11 0.13 0.11 0.09 0.24 0.02
## insom5 0.24 0.13 0.08 0.14 0.13 0.07 0.22 0.02
A pesar de los problemas con el ítem 3, la escala tiene un alpha adecuado (std.alpha = .74), pero que podría
ser un poco mejor al eliminar este ítem (.78), que tiene una correlación con el total relativamente baja (r.cor
= .32).
En estos casos, la decisión es más conceptual que estadística. Considerando el contenido del ítem 3 “A veces
me despierto mucho antes de lo que tenía presupuestado”, quizás sea mejor eliminarlo de la escala y ocuparlo
por separado, ya que se refiere a un tipo de insomnio diferente, que además es menos frecuente en personas
jóvenes.
Antes de calcular el puntaje de insomnio sin el ítem 3, revisemos la confiabilidad de esta nueva escala. Ahora
que no podemos ocupar el objeto insomnio que habíamos creado antes, tenemos que escribir cada una de las
variables en la base de datos estudio2012.
La función cbind() combina objetos de R, en este caso columnas en la base de datos estudio2012. También
podríamos haber ocupado data.frame().
with(estudio2012,
alpha(cbind(insom1, insom2, insom4, insom5)))
##
## Reliability analysis

41
## Call: alpha(x = cbind(insom1, insom2, insom4, insom5))
##
## raw_alpha std.alpha G6(smc) average_r S/N ase mean sd
## 0.77 0.78 0.82 0.46 3.4 0.038 3.7 1.7
##
## lower alpha upper 95% confidence boundaries
## 0.7 0.77 0.84
##
## Reliability if an item is dropped:
## raw_alpha std.alpha G6(smc) average_r S/N alpha se
## insom1 0.67 0.67 0.60 0.40 2.0 0.053
## insom2 0.67 0.67 0.60 0.41 2.0 0.053
## insom4 0.74 0.75 0.79 0.50 3.0 0.047
## insom5 0.77 0.78 0.80 0.54 3.5 0.041
##
## Item statistics
## n raw.r std.r r.cor r.drop mean sd
## insom1 111 0.81 0.83 0.85 0.65 3.4 2.0
## insom2 111 0.81 0.83 0.85 0.65 3.3 2.0
## insom4 110 0.75 0.73 0.58 0.53 4.1 2.2
## insom5 110 0.73 0.70 0.53 0.47 3.9 2.3
##
## Non missing response frequency for each item
## 1 2 3 4 5 6 7 miss
## insom1 0.20 0.22 0.19 0.09 0.06 0.14 0.11 0.01
## insom2 0.24 0.22 0.14 0.09 0.13 0.09 0.09 0.01
## insom4 0.15 0.17 0.11 0.13 0.11 0.09 0.24 0.02
## insom5 0.24 0.13 0.08 0.14 0.13 0.07 0.22 0.02
Ahora el alpha subió a .78, y vemos que los ítems 4 y 5 funcionan un poco peor. Más adelante vamos a ver
por qué, pero por ahora vamos a calcular la escala de insomnio con estos cuatro ítems.

Calculo de escalas:

Para simplificar las cosas, antes habíamos calculado la escala sumando las variables y dividiendo por el
número de elementos. El principal problema de esto es que no permite especificar qué hacer con los datos
perdidos. Al incluir na.rm=TRUE en la función rowMeans(), especificamos que si alguien contestá solamente
algunos ítems se calcule el promedio con la información que está disponible. De otra forma ese participante
quedaba con un valor NA en esta escala. Ocupando esta opción, un participante queda con NA solamente
cuando no ha contestado ninguno de los ítems.
estudio2012$insom = with(estudio2012,
rowMeans(cbind(insom1, insom2, insom4, insom5),
na.rm=TRUE))

summary(estudio2012$insom)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 1.00 2.50 3.50 3.67 4.75 7.00 1
Revisemos los ítems de ansiedad ante evaluaciones:
names(estudio2012) # ¿Se acuerdan cuál era el nombre de estas variables?
x = cor(with(estudio2012,
cbind(ansev1, ansev2, ansev3, ansev4, ansev5)),

42
use = "pairwise.complete.obs")

round(x, 2)
## ansev1 ansev2 ansev3 ansev4 ansev5
## ansev1 1.00 0.53 0.32 0.32 0.17
## ansev2 0.53 1.00 0.23 0.31 0.19
## ansev3 0.32 0.23 1.00 0.47 0.31
## ansev4 0.32 0.31 0.47 1.00 0.40
## ansev5 0.17 0.19 0.31 0.40 1.00
cor.plot(x)

Correlation plot

1
ansev1 0.8
0.6
ansev2 0.4
0.2
ansev3
0
−0.2
ansev4
−0.4
−0.6
ansev5
−0.8
−1
ansev1

ansev2

ansev3

ansev4

ansev5

Esta escala se ve mucho mejor, ya que todos los ítems correlacionan entre si.
alpha(with(estudio2012,
cbind(ansev1, ansev2, ansev3, ansev4, ansev5)))
##
## Reliability analysis
## Call: alpha(x = with(estudio2012, cbind(ansev1, ansev2, ansev3, ansev4,
## ansev5)))
##
## raw_alpha std.alpha G6(smc) average_r S/N ase mean sd
## 0.71 0.71 0.69 0.32 2.4 0.044 4 1.3
##
## lower alpha upper 95% confidence boundaries
## 0.62 0.71 0.79
##
## Reliability if an item is dropped:
## raw_alpha std.alpha G6(smc) average_r S/N alpha se
## ansev1 0.65 0.65 0.60 0.32 1.9 0.054
## ansev2 0.66 0.66 0.61 0.33 2.0 0.052

43
## ansev3 0.65 0.65 0.62 0.32 1.9 0.053
## ansev4 0.63 0.62 0.59 0.29 1.7 0.058
## ansev5 0.69 0.69 0.66 0.36 2.3 0.047
##
## Item statistics
## n raw.r std.r r.cor r.drop mean sd
## ansev1 111 0.70 0.69 0.59 0.48 3.8 2.0
## ansev2 111 0.68 0.67 0.56 0.45 3.1 1.9
## ansev3 110 0.68 0.69 0.57 0.48 4.5 1.8
## ansev4 111 0.74 0.74 0.65 0.54 4.1 2.0
## ansev5 111 0.60 0.61 0.45 0.37 4.6 1.8
##
## Non missing response frequency for each item
## 1 2 3 4 5 6 7 miss
## ansev1 0.15 0.23 0.08 0.10 0.18 0.19 0.07 0.01
## ansev2 0.27 0.23 0.12 0.08 0.16 0.07 0.06 0.01
## ansev3 0.08 0.08 0.11 0.15 0.24 0.24 0.11 0.02
## ansev4 0.14 0.09 0.20 0.10 0.18 0.13 0.16 0.01
## ansev5 0.06 0.08 0.13 0.16 0.22 0.18 0.17 0.01
La confiabilidad es adecuada (.71) y no mejora al eliminar ningún ítem.
estudio2012$ansev = with(estudio2012,
rowMeans(cbind(ansev1, ansev2, ansev3, ansev4, ansev5),
na.rm=TRUE))

describe(estudio2012$ansev)
## vars n mean sd median trimmed mad min max range skew kurtosis se
## X1 1 111 4.03 1.29 4 4 1.48 1 7 6 0.15 -0.51 0.12

Análisis factorial

Es perfectamente posible que una serie de ítems que fueron desarrollados para medir un constructo están en
realidad midiendo dos o tres. Eso es justamente lo que está ocurriendo con los ítems de insomnio. Aunque
ahora nos vamos a concentrar en el análisis estadístico, este proceso debiera integrar también un análisis
teórico y conceptual.
Entender exactamente cómo funciona un análisis factorial es mucho más avanzado de lo que vamos a cubrir
en el curso. Pero eso no significa que no lo podamos ocupar.
¿Cuántos factores estamos midiendo con los ítems de insomnio? Una forma de responder a esta pregunta es
ejecutar la siguiente función:
fa.parallel(insomnio)

44
eigenvalues of principal components and factor analysis
Parallel Analysis Scree Plots
2.5

PC Actual Data
PC Simulated Data
2.0

PC Resampled Data
FA Actual Data
FA Simulated Data
1.5

FA Resampled Data
1.0
0.5
0.0

1 2 3 4 5

Factor/Component Number
## Parallel analysis suggests that the number of factors = 2 and the number of components = 2
fa.parallel() es una función de la librería psych nos ayuda a evaluar cuál es la solución más optima en
términos de cantidad de factores considerando parsimonia -donde tener menos factores es mejor- y ajuste con
los datos -donde tener más factores es mejor.
El gráfico entrega más información de la que realmente necesitamos, lo que importa es la línea de FA (análisis
factorial). El primer factor logra explicar más varianza en la escala que el segundo factor, que a su vez logra
explicar más varianza en la escala que el tercer factor. Agregar un tercer factor es ciertamente poco práctico,
ya que dos factores pueden explicar la mayor parte de la varianza.
Con esta información, podemos hacer un análisis factorial exploratorio con dos factores, ocupando la función
fa() de la librería psych.
fa(insomnio, # las variables a incluir en el análisis
2) # la cantidad de factores
## Loading required namespace: GPArotation
## Factor Analysis using method = minres
## Call: fa(r = insomnio, nfactors = 2)
## Standardized loadings (pattern matrix) based upon correlation matrix
## MR1 MR2 h2 u2 com
## insom1 0.99 -0.01 0.98 0.025 1.0
## insom2 0.90 0.03 0.84 0.164 1.0
## insom3 0.41 -0.09 0.15 0.853 1.1
## insom4 0.15 0.59 0.43 0.567 1.1
## insom5 -0.04 0.89 0.77 0.235 1.0
##
## MR1 MR2
## SS loadings 2.00 1.15

45
## Proportion Var 0.40 0.23
## Cumulative Var 0.40 0.63
## Proportion Explained 0.63 0.37
## Cumulative Proportion 0.63 1.00
##
## With factor correlations of
## MR1 MR2
## MR1 1.00 0.39
## MR2 0.39 1.00
##
## Mean item complexity = 1
## Test of the hypothesis that 2 factors are sufficient.
##
## The degrees of freedom for the null model are 10 and the objective function was 2.38 with Chi Squa
## The degrees of freedom for the model are 1 and the objective function was 0
##
## The root mean square of the residuals (RMSR) is 0
## The df corrected root mean square of the residuals is 0.01
##
## The harmonic number of observations is 110 with the empirical chi square 0.04 with prob < 0.84
## The total number of observations was 112 with Likelihood Chi Square = 0.21 with prob < 0.65
##
## Tucker Lewis Index of factoring reliability = 1.032
## RMSEA index = 0 and the 90 % confidence intervals are NA 0.193
## BIC = -4.51
## Fit based upon off diagonal values = 1
## Measures of factor score adequacy
## MR1 MR2
## Correlation of scores with factors 0.99 0.90
## Multiple R square of scores with factors 0.98 0.81
## Minimum correlation of possible factor scores 0.96 0.61
La información entregada en la primera tabla nos indica cuánto se relaciona cada ítem con cada uno de los
factores. Esto puede verse de forma gráfica con
plot(fa(insomnio,2))

46
Factor Analysis

5
0.8
0.6

4
MR2

0.4
0.2
0.0

2
1
3
0.0 0.2 0.4 0.6 0.8 1.0

MR1
Los ítems 1 y 2 se relacionan fuertemente con el primer factor (MR1), y los ítems 4 y 5 se relacionan
fuertemente con el segundo factor (MR2). El ítem 3 está más relacionado con el primer factor (.41) que con
el segundo (-.09).
¿Qué significa esto? Significa que la escala mide dos cosas, que de hecho son perfectamente comprensibles al
leer los ítems:
Factor 1: Problemas de insomnio.
Generalmente me cuesta conciliar el sueño o despierto muchas veces en la noche (insom1)
Suelo presentar grandes dificultades para iniciar y mantener el sueño (insom2)
A veces me despierto mucho antes de lo que tenía presupuestado (insom3)
Factor 2: Conductas problemáticas de higiene del sueño.
Cuando es hora de dormir, me dan ganas de ver televisión, leer o hacer otra cosa (insom4)
Suelo tener horarios de sueño desordenados, dormir siestas o pasar un tiempo excesivo en la cama (insom5)
Obviamente estos dos constructos están relacionados, de hecho tienen una correlación de .39 según el análisis
factorial. Pero no son lo mismo.
Revisemos la confiabilidad antes de calcular cada escala.
Problemas de insomnio:
alpha(with(estudio2012,
cbind(insom1, insom2, insom3)))
##
## Reliability analysis
## Call: alpha(x = with(estudio2012, cbind(insom1, insom2, insom3)))
##
## raw_alpha std.alpha G6(smc) average_r S/N ase mean sd
## 0.78 0.78 0.8 0.54 3.5 0.039 3.3 1.7
##
## lower alpha upper 95% confidence boundaries

47
## 0.7 0.78 0.85
##
## Reliability if an item is dropped:
## raw_alpha std.alpha G6(smc) average_r S/N alpha se
## insom1 0.51 0.51 0.35 0.35 1.1 0.0920
## insom2 0.54 0.54 0.37 0.37 1.2 0.0872
## insom3 0.95 0.95 0.90 0.90 18.4 0.0097
##
## Item statistics
## n raw.r std.r r.cor r.drop mean sd
## insom1 111 0.91 0.91 0.93 0.77 3.4 2
## insom2 111 0.90 0.90 0.92 0.76 3.3 2
## insom3 110 0.69 0.69 0.38 0.37 3.1 2
##
## Non missing response frequency for each item
## 1 2 3 4 5 6 7 miss
## insom1 0.20 0.22 0.19 0.09 0.06 0.14 0.11 0.01
## insom2 0.24 0.22 0.14 0.09 0.13 0.09 0.09 0.01
## insom3 0.32 0.18 0.11 0.09 0.13 0.12 0.05 0.02
El alpha es .78. Podría eliminarse el item 3, como hicimos antes, pero por ahora lo vamos a mantener.
estudio2012$insom = with(estudio2012,
rowMeans(cbind(insom1, insom2, insom3),
na.rm=TRUE))
summary(estudio2012$insom)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 1.00 2.00 3.00 3.26 4.33 7.00 1
Conductas problemáticas insomnio:
alpha(with(estudio2012,
cbind(insom4, insom5)))
## Warning in matrix(unlist(drop.item), ncol = 8, byrow = TRUE): data length
## [12] is not a sub-multiple or multiple of the number of columns [8]
##
## Reliability analysis
## Call: alpha(x = with(estudio2012, cbind(insom4, insom5)))
##
## raw_alpha std.alpha G6(smc) average_r S/N ase mean sd
## 0.71 0.71 0.56 0.56 2.5 0.054 4 2
##
## lower alpha upper 95% confidence boundaries
## 0.61 0.71 0.82
##
## Reliability if an item is dropped:
## raw_alpha std.alpha G6(smc) average_r S/N alpha se
## insom4 0.56 0.56 0.31 0.56 NA NA
## insom5 0.31 0.56 NA NA 0.56 0.07
##
## Item statistics
## n raw.r std.r r.cor r.drop mean sd
## insom4 110 0.88 0.88 0.66 0.56 4.1 2.2
## insom5 110 0.89 0.88 0.66 0.56 3.9 2.3

48
##
## Non missing response frequency for each item
## 1 2 3 4 5 6 7 miss
## insom4 0.15 0.17 0.11 0.13 0.11 0.09 0.24 0.02
## insom5 0.24 0.13 0.08 0.14 0.13 0.07 0.22 0.02
El alpha es .71, aunque con dos ítems normalmente se reporta la correlación (.56)
estudio2012$cinsom = with(estudio2012,
rowMeans(cbind(insom4, insom5),
na.rm=TRUE))

summary(estudio2012$cinsom)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 1.00 2.00 4.00 3.98 5.50 7.00 1
¿qué pasa cuando hacemos un análisis factorial para los ítems de ansiedad en periodo de evaluaciones? De
acuerdo al scree plot,
fa.parallel(with(estudio2012,
cbind(ansev1, ansev2, ansev3, ansev4, ansev5)))
eigenvalues of principal components and factor analysis

Parallel Analysis Scree Plots

PC Actual Data
2.0

PC Simulated Data
PC Resampled Data
FA Actual Data
1.5

FA Simulated Data
FA Resampled Data
1.0
0.5
0.0

1 2 3 4 5

Factor/Component Number
## Parallel analysis suggests that the number of factors = 2 and the number of components = 1
parece que la mejor solución es ocupar dos factores.
x = fa(with(estudio2012,
cbind(ansev1, ansev2, ansev3, ansev4, ansev5)), 2)
x
## Factor Analysis using method = minres

49
## Call: fa(r = with(estudio2012, cbind(ansev1, ansev2, ansev3, ansev4,
## ansev5)), nfactors = 2)
##
## Warning: A Heywood case was detected.
## Standardized loadings (pattern matrix) based upon correlation matrix
## MR2 MR1 h2 u2 com
## ansev1 -0.01 1.00 1.00 0.005 1.0
## ansev2 0.19 0.45 0.32 0.685 1.4
## ansev3 0.56 0.09 0.37 0.633 1.0
## ansev4 0.79 -0.01 0.62 0.379 1.0
## ansev5 0.53 -0.05 0.26 0.738 1.0
##
## MR2 MR1
## SS loadings 1.30 1.26
## Proportion Var 0.26 0.25
## Cumulative Var 0.26 0.51
## Proportion Explained 0.51 0.49
## Cumulative Proportion 0.51 1.00
##
## With factor correlations of
## MR2 MR1
## MR2 1.00 0.43
## MR1 0.43 1.00
##
## Mean item complexity = 1.1
## Test of the hypothesis that 2 factors are sufficient.
##
## The degrees of freedom for the null model are 10 and the objective function was 0.96 with Chi Squa
## The degrees of freedom for the model are 1 and the objective function was 0
##
## The root mean square of the residuals (RMSR) is 0.01
## The df corrected root mean square of the residuals is 0.03
##
## The harmonic number of observations is 111 with the empirical chi square 0.26 with prob < 0.61
## The total number of observations was 112 with Likelihood Chi Square = 0.31 with prob < 0.58
##
## Tucker Lewis Index of factoring reliability = 1.075
## RMSEA index = 0 and the 90 % confidence intervals are NA 0.205
## BIC = -4.41
## Fit based upon off diagonal values = 1
## Measures of factor score adequacy
## MR2 MR1
## Correlation of scores with factors 0.86 1.00
## Multiple R square of scores with factors 0.74 1.00
## Minimum correlation of possible factor scores 0.48 0.99
plot(x)

50
Factor Analysis
1.0
1
0.8
0.6
MR1

0.4

2
0.2

3
0.0

5 4

0.0 0.2 0.4 0.6 0.8

MR2
Los ítems 3, 4 y 5 cargan en un factor (MR2), y los ítems 1 y 2 cargan en otro (MR1). El factor MR2
puede ser más propiamente llamado ansiedad en periodo de evaluaciones (irritable, dolores e incapacidad de
desconectarse), el segundo factor son los ítems de insomnio durante este periodo. Al revisar la confiabilidad
que tendrían estas escalas,
alpha(with(estudio2012,
cbind(ansev3, ansev4, ansev5))) # alpha = .66
##
## Reliability analysis
## Call: alpha(x = with(estudio2012, cbind(ansev3, ansev4, ansev5)))
##
## raw_alpha std.alpha G6(smc) average_r S/N ase mean sd
## 0.66 0.66 0.57 0.39 1.9 0.055 4.4 1.4
##
## lower alpha upper 95% confidence boundaries
## 0.55 0.66 0.77
##
## Reliability if an item is dropped:
## raw_alpha std.alpha G6(smc) average_r S/N alpha se
## ansev3 0.57 0.57 0.40 0.40 1.3 0.081
## ansev4 0.47 0.47 0.31 0.31 0.9 0.100
## ansev5 0.64 0.64 0.47 0.47 1.8 0.068
##
## Item statistics
## n raw.r std.r r.cor r.drop mean sd
## ansev3 110 0.76 0.77 0.58 0.47 4.5 1.8
## ansev4 111 0.83 0.81 0.66 0.54 4.1 2.0
## ansev5 111 0.73 0.74 0.50 0.42 4.6 1.8
##
## Non missing response frequency for each item

51
## 1 2 3 4 5 6 7 miss
## ansev3 0.08 0.08 0.11 0.15 0.24 0.24 0.11 0.02
## ansev4 0.14 0.09 0.20 0.10 0.18 0.13 0.16 0.01
## ansev5 0.06 0.08 0.13 0.16 0.22 0.18 0.17 0.01
alpha(with(estudio2012,
cbind(ansev1, ansev2))) # r = .53
## Warning in matrix(unlist(drop.item), ncol = 8, byrow = TRUE): data length
## [12] is not a sub-multiple or multiple of the number of columns [8]
##
## Reliability analysis
## Call: alpha(x = with(estudio2012, cbind(ansev1, ansev2)))
##
## raw_alpha std.alpha G6(smc) average_r S/N ase mean sd
## 0.69 0.69 0.53 0.53 2.3 0.058 3.4 1.7
##
## lower alpha upper 95% confidence boundaries
## 0.58 0.69 0.81
##
## Reliability if an item is dropped:
## raw_alpha std.alpha G6(smc) average_r S/N alpha se
## ansev1 0.53 0.53 0.28 0.53 NA NA
## ansev2 0.28 0.53 NA NA 0.53 0.069
##
## Item statistics
## n raw.r std.r r.cor r.drop mean sd
## ansev1 111 0.88 0.87 0.64 0.53 3.8 2.0
## ansev2 111 0.87 0.87 0.64 0.53 3.1 1.9
##
## Non missing response frequency for each item
## 1 2 3 4 5 6 7 miss
## ansev1 0.15 0.23 0.08 0.10 0.18 0.19 0.07 0.01
## ansev2 0.27 0.23 0.12 0.08 0.16 0.07 0.06 0.01
vemos que es usable, pero ciertamente no es buena. ¿qué hacer en este caso? La respuesta no está en los
análisis estadísticos, sino en un análisis conceptual y de los objetivos de investigación. Los dos ítems de
insomnio (ansev1 y ansev2) no correlacionan muy bien con el resto de la escala, y además ya tenemos otra
escala para medir insomnio en general. Por lo tanto, creo que lo mejor es ocupar solamente el primer factor
sin incluir los ítems de insomnio.
estudio2012$ansev = with(estudio2012,
rowMeans(cbind(ansev3, ansev4, ansev5),
na.rm=TRUE))

summary(estudio2012$ansev)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 1.00 3.33 4.67 4.42 5.67 7.00 1

Itemes invertidos.

Es común que las escalas incluyan ítems invertidos, donde un mayor puntaje en el item refleja un menor nivel
en el constructo que se quiere medir. Por ejemplo, la escala de “tolerancia hacia la diversidad sexual” tiene
los siguientes ítems:

52
(tolsex1) Me siento incómodo compartiendo socialmente con personas que son de distinta orientación sexual a
la mía.
(tolsex2) Las relaciones de pareja no heterosexuales son “anti naturales”.
(tolsex3) Las parejas del mismo sexo no deberían andar de la mano ni besarse en público.
(tolsex4) Considero que el matrimonio debiera ser sólo entre un hombre y una mujer.
(tolsex5) Me gustaría que cambiaran las leyes para promover un mayor respeto a las minorías sexuales.
En realidad, esta escala debiera llamarse intolerancia a la diversidad sexual. Un mayor puntaje en los ítems
1, 2, 3 o 4 se asocia a una mayor intolerancia. Pero el quinto ítem está invertido: un mayor puntaje se asocia
a una menor intolerancia.
Veamos que pasa con estos ítems en un análisis factorial.
tolsex = with(estudio2012,
data.frame(tolsex1, tolsex2, tolsex3, tolsex4, tolsex5))

fa.parallel(tolsex)
eigenvalues of principal components and factor analysis

Parallel Analysis Scree Plots

PC Actual Data
2.5

PC Simulated Data
PC Resampled Data
2.0

FA Actual Data
FA Simulated Data
1.5

FA Resampled Data
1.0
0.5
0.0

1 2 3 4 5

Factor/Component Number
## Parallel analysis suggests that the number of factors = 1 and the number of components = 1
A diferencia de las escalas que revisamos antes, estos ítems se agrupan claramente en un factor.
fa(tolsex)
## Factor Analysis using method = minres
## Call: fa(r = tolsex)
## Standardized loadings (pattern matrix) based upon correlation matrix
## MR1 h2 u2 com
## tolsex1 0.25 0.063 0.94 1
## tolsex2 0.80 0.640 0.36 1
## tolsex3 0.75 0.565 0.43 1

53
## tolsex4 0.88 0.774 0.23 1
## tolsex5 -0.61 0.367 0.63 1
##
## MR1
## SS loadings 2.41
## Proportion Var 0.48
##
## Mean item complexity = 1
## Test of the hypothesis that 1 factor is sufficient.
##
## The degrees of freedom for the null model are 10 and the objective function was 1.81 with Chi Squa
## The degrees of freedom for the model are 5 and the objective function was 0.03
##
## The root mean square of the residuals (RMSR) is 0.03
## The df corrected root mean square of the residuals is 0.05
##
## The harmonic number of observations is 111 with the empirical chi square 2.38 with prob < 0.79
## The total number of observations was 112 with Likelihood Chi Square = 3.12 with prob < 0.68
##
## Tucker Lewis Index of factoring reliability = 1.02
## RMSEA index = 0 and the 90 % confidence intervals are NA 0.102
## BIC = -20.47
## Fit based upon off diagonal values = 1
## Measures of factor score adequacy
## MR1
## Correlation of scores with factors 0.94
## Multiple R square of scores with factors 0.88
## Minimum correlation of possible factor scores 0.75
plot(fa(tolsex))
Factor Analysis

4
2 3
0.5
load

1
0.0
−0.5

5
1 2 3 4 5

Index

54
Como debiera ser, el ítem 5 tiene una relación negativa con el factor. Esto está indicado al comienzo de
los resultados del análisis factorial, en la columna MR1 de las cargas (loadings) estandarizadas. Además, el
ítem 1 parece no estar funcionando muy bien con el resto de la escala, su relación con el factor general es
claramente menor al resto (0.25).
Para calcular el alpha es fundamental agregar la opción check.keys=TRUE cuando hay ítemes invertidos (en
caso contrario el output incluye una advertencia de todas formas). Al agregar este parámetro R invierte
automáticamente los ítemes que tienen una correlación negativa con el resto, y agrega un mensaje de
advertencia. El item invertido tiene un signo menos junto al nombre (tolsex5-).
alpha(tolsex, check.keys=TRUE)
## Warning in alpha(tolsex, check.keys = TRUE): Some items were negatively correlated with total scale a
## This is indicated by a negative sign for the variable name.
##
## Reliability analysis
## Call: alpha(x = tolsex, check.keys = TRUE)
##
## raw_alpha std.alpha G6(smc) average_r S/N ase mean sd
## 0.79 0.79 0.78 0.43 3.7 0.029 2.2 1.4
##
## lower alpha upper 95% confidence boundaries
## 0.73 0.79 0.85
##
## Reliability if an item is dropped:
## raw_alpha std.alpha G6(smc) average_r S/N alpha se
## tolsex1 0.83 0.84 0.81 0.57 5.4 0.024
## tolsex2 0.71 0.71 0.69 0.38 2.5 0.041
## tolsex3 0.72 0.71 0.70 0.38 2.4 0.039
## tolsex4 0.69 0.69 0.66 0.36 2.2 0.047
## tolsex5- 0.75 0.75 0.75 0.43 3.1 0.034
##
## Item statistics
## n raw.r std.r r.cor r.drop mean sd
## tolsex1 111 0.45 0.49 0.28 0.24 1.9 1.5
## tolsex2 111 0.81 0.80 0.77 0.69 2.0 1.7
## tolsex3 111 0.80 0.81 0.76 0.69 1.9 1.5
## tolsex4 111 0.88 0.85 0.84 0.74 2.9 2.4
## tolsex5- 111 0.73 0.72 0.61 0.55 2.2 1.9
##
## Non missing response frequency for each item
## 1 2 3 4 5 6 7 miss
## tolsex1 0.59 0.20 0.08 0.05 0.02 0.03 0.04 0.01
## tolsex2 0.65 0.11 0.07 0.06 0.04 0.02 0.05 0.01
## tolsex3 0.65 0.13 0.06 0.04 0.08 0.04 0.01 0.01
## tolsex4 0.58 0.03 0.04 0.05 0.07 0.08 0.15 0.01
## tolsex5 0.06 0.04 0.04 0.10 0.05 0.10 0.62 0.01
El alpha de la escala es bueno (.79), pero quedaría mejor si se elimina el ítem 1 (.84).
Nuevamente, esta decisión tiene que ser conceptual también. A mí me parece adecuado eliminarlo, no porque
sea un mal ítem, sino porque está midiendo algo ligeramente distinto -una reacción emocional vs. actitudes
conservadoras más discursivas.
Antes de promediar los ítems, en todo caso, ¡tenemos que invertir los valores de tolsex5! Lo más fácil es
hacerlo directamente con la fórmula:

55
Puntaje invertido = Máximo + Mínimo - Puntaje original.
estudio2012$tolsex5i = 7 + 1 - estudio2012$tolsex5

summary(estudio2012$tolsex5i)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 1.00 1.00 1.00 2.19 3.00 7.00 1
with(estudio2012, cor(tolsex5, tolsex5i, use="pairwise.complete.obs"))
## [1] -1
Ahora podemos calcular la escala, donde un mayor puntaje va a reflejar un menor nivel de tolerancia hacia la
diversidad sexual. Por lo tanto, vamos a aprovechar de cambiarle el nombre a “intolsex” (mayor puntaje
mayor intolerancia)
estudio2012$intolsex = with(estudio2012,
rowMeans(cbind(tolsex2, tolsex3, tolsex4, tolsex5i),
na.rm=TRUE))

summary(estudio2012$intolsex)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 1.00 1.00 1.25 2.25 3.00 7.00 1

Contraste de hipótesis y estimación de parámetros poblacionales


Hasta ahora, hemos visto una serie de análisis, gráficos y tablas para visualizar la información obtenida en
la muestra. Las siguientes secciones tratan en cambio sobre la estimación de lo que está ocurriendo en la
población, a partir de los datos muestrales.

Chi-cuadrado, relaciones entre variables categóricas.

En las secciones anteriores vimos cómo producir una tabla para ver la cantidad de personas que pertenecen a
ciertos grupos o categorías,
table(estudio2012$sitsentf)
##
## En una relacion Es complicado Soltero/a
## 54 8 49
o hacer un cruce entre dos variables categóricas, como por ejemplo comparar la situación sentimental de
hombres y mujeres:
table(estudio2012$sitsentf, estudio2012$generof)
##
## Mujer Hombre
## En una relacion 44 9
## Es complicado 4 4
## Soltero/a 33 14
¿Cómo saber si estas dos variables están relacionadas? ¿Es más probable que los hombres tengan relaciones
complicadas? El análisis que corresponde ocupar para contestar esta pregunta es un análisis de chi-cuadrado,
que puede aplicarse a la frecuencia de una sola variable categórica, o a un cruce de varias variables.

56
La función para hacer un análisis de chi-cuadrado es chisq.test(), y requiere la información de una tabla
de frecuencia -que puede obtenerse con table(). Por ejemplo,
table(estudio2012$generof) # Obtiene la cantidad de hombres y mujeres en la muestra.
##
## Mujer Hombre
## 82 27
chisq.test(table(estudio2012$generof)) # Hace un análisis de chi-cuadrado con esta tabla.
##
## Chi-squared test for given probabilities
##
## data: table(estudio2012$generof)
## X-squared = 28, df = 1, p-value = 1e-07
A partir de este análisis de chi-cuadrado vemos que la probabilidad de que nuestra muestra venga de una
población donde hay igual cantidad de hombres y mujeres es tremendamente baja (χ2 = 27.75, p < .001).
Esto nos indica que debemos rechazar esta hipótesis nula y concluir que en la carrera de psicología en nuestra
universidad hay más mujeres que hombres.
Al parecer las mujeres tienen menos probabilidades de estar solteras que los hombres, quienes además tienen
más probabilidades de estar en relaciones complicadas.
table(estudio2012$sitsentf, estudio2012$generof)
##
## Mujer Hombre
## En una relacion 44 9
## Es complicado 4 4
## Soltero/a 33 14
Veamos si podemos generalizar esto a la población de estudiantes de psicología.
chisq.test(table(estudio2012$sitsentf, estudio2012$generof))
## Warning in chisq.test(table(estudio2012$sitsentf, estudio2012$generof)):
## Chi-squared approximation may be incorrect
##
## Pearson's Chi-squared test
##
## data: table(estudio2012$sitsentf, estudio2012$generof)
## X-squared = 5.1, df = 2, p-value = 0.08
Como se observa en los resultados, la relación entre estas variables no alcanza a ser estadísticamente
significativa (χ2 = 5.05, p = .08). Además, R imprime un mensaje advirtiendo que la estimación del
chi-cuadrado puede ser incorrecta. Esto se debe a que hay muy pocas mujeres y muy pocos hombres (menos
de 5) que tienen una relación complicada.
La función table() tiene un argumento especialmente diseñado para estos casos, es decir, para excluir ciertas
categorías del análisis:
table(estudio2012$sitsentf, estudio2012$generof,
exclude="Es complicado")
##
## Mujer Hombre
## En una relacion 44 9
## Soltero/a 33 14

57
Esta vez, vamos a asignar el resultado del análisis a un objeto llamado x2 (podríamos haber puesto cualquier
nombre)
x2 = chisq.test(table(estudio2012$sitsentf, estudio2012$generof,
exclude="Es complicado"))

x2
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: table(estudio2012$sitsentf, estudio2012$generof, exclude = "Es complicado")
## X-squared = 1.6, df = 1, p-value = 0.2
La probabilidad de que esta muestra venga de una población donde el género no se relaciona con estar
soltero(a) o en un una relación es mayor a .05 (χ2 = 1.64, p = .20), por lo que no corresponde rechazar la
hipótesis nula. Los hombres y las mujeres que están estudiando psicología tienen la misma probabilidad de
estar en una relación.
También podríamos haber ocupado una simulación para calcular el valor de p, lo que es más adecuado cuando
tenemos poco n. El resultado es básicamente el mismo, no hay una relación significativa entre género y
situación sentimental.
chisq.test(table(estudio2012$sitsentf, estudio2012$generof),
simulate.p.value=TRUE)
##
## Pearson's Chi-squared test with simulated p-value (based on 2000
## replicates)
##
## data: table(estudio2012$sitsentf, estudio2012$generof)
## X-squared = 5.1, df = NA, p-value = 0.06
El análisis de chi-cuadrado, como la mayoría de los análisis que vamos a ver de ahora en adelante, son objetos
más complejos que los que hemos visto hasta ahora.
Si bien ejecutar
x2 # el nombre del objeto al que asignamos el análisis de chi-cuadrado
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: table(estudio2012$sitsentf, estudio2012$generof, exclude = "Es complicado")
## X-squared = 1.6, df = 1, p-value = 0.2
nos entrega la información básica, el objeto x2 tiene más información. Para acceder a esta información se
ocupa el mismo formato que para seleccionar una variable en una base de datos. Por ejemplo, para obtener
la tabla de valores observados, podemos ocupar
x2$observed
##
## Mujer Hombre
## En una relacion 44 9
## Soltero/a 33 14
lo que es exactamente lo mismo que la tabla original con que hicimos el análisis. Para obtener los valores
esperados según la hipótesis nula, podemos ejecutar
x2$expected

58
##
## Mujer Hombre
## En una relacion 40.81 12.19
## Soltero/a 36.19 10.81
En cualquier análisis, los valores que pueden obtenerse están listados en la página de ayuda.
help(chisq.test) # ver "Value"

Estimación del promedio poblacional y relaciones entre variables


categóricas y numéricas.

Prueba t

Prueba t para una muestra: Estimación del promedio de la población.

En caso de querer estimar los niveles poblacionales de una variable numérica, pueden hacer una prueba t
para una muestra en esta variable con la función t.test(). Por ejemplo, los datos de escala de intolerancia
a la diversidad sexual
t.test(estudio2012$intolsex)
##
## One Sample t-test
##
## data: estudio2012$intolsex
## t = 15, df = 110, p-value <2e-16
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## 1.950 2.541
## sample estimates:
## mean of x
## 2.245
indican que el promedio poblacional está entre 1.95 y 2.54 ocupando un intervalo de confianza de 95%.
Considerando que la escala es de 1 a 7, el nivel es bastante bajo. Por defecto, la hipótesis nula de esta prueba
es que el promedio poblacional es igual a cero, algo que por supuesto no tiene sentido en esta escala de 1 a 7.
Para cambiar la hipótesis nula, por ejemplo para estimar la probabilidad de que esta muestra venga de una
población en que el promedio es cuatro (el punto medio de la escala), es necesario agregar el parámetro mu:
t.test(estudio2012$intolsex, mu=4)
##
## One Sample t-test
##
## data: estudio2012$intolsex
## t = -12, df = 110, p-value <2e-16
## alternative hypothesis: true mean is not equal to 4
## 95 percent confidence interval:
## 1.950 2.541
## sample estimates:
## mean of x
## 2.245
Obviamente, la probabilidad es tremendamente baja (p < 2.2e-16). Eso son 16 ceros antes del 2.2 (2.2 x 10
elevado a 16).

59
format(2.2e-16, scientific=FALSE)
## [1] "0.00000000000000022"
La librería psych incluye un comando para hacer gráficos con barras de error ocupando intervalos de confianza.
Es ciertamente una mejor versión que poner solamente los promedios en el gráfico.
error.bars(with(estudio2012,
data.frame(ansev1, ansev2, ansev3, ansev4, ansev5)),
ylim=c(1,7), bars=TRUE, xpd=FALSE)
95% confidence limits
7
6
Dependent Variable

5
4
3
2
1

ansev1 ansev2 ansev3 ansev4 ansev5

Independent Variable
Este gráfico puede ser una forma útil de comparar los niveles de diferentes variables considerando información
de estadística inferencial, pero es importante destacar que no es una prueba de hipótesis estadísticas. Son
estimaciones independientes del promedio poblacional en cada ítem.

Prueba t para muestras independientes: Comparación del promedio de dos grupos.

La misma función que ocupamos en la sección anterior, t.test(), puede ser ocupada para comparar los
promedios de dos grupos de participantes, y evaluar la hipótesis nula de que ambos tienen el mismo promedio
en la población. El formato para hacer este análisis es el mismo que ya hemos visto otras veces: la variable
dependiente predicha por la variable independiente (y~x). A modo de ejemplo, podemos evaluar si los niveles
de intolerancia a la diversidad sexual son diferentes según el género de los participantes:
t.test(estudio2012$intolsex~estudio2012$generof)
##
## Welch Two Sample t-test
##
## data: estudio2012$intolsex by estudio2012$generof
## t = 2.5, df = 65, p-value = 0.02
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:

60
## 0.1401 1.2920
## sample estimates:
## mean in group Mujer mean in group Hombre
## 2.392 1.676
Curiosamente, las mujeres muestran mayores niveles de intolerancia que los hombres (t(64) = 2.48, p = .02).
Es importante recordar que estos resultados son generalizables a una población particular; estudiantes de
psicología de nuestra universidad, y no a los hombres y mujeres de chile, por ejemplo. Al revisar los resultados
de otras variables, como opiniones hacia el aborto y orientación política, pareciera que las mujeres tienden a
ser más conservadoras que los hombres en esta población, lo que podría explicar las diferencias en tolerancia
hacia la diversidad sexual.
table(estudio2012$orienpolf, estudio2012$generof)
##
## Mujer Hombre
## Izquierda 10 8
## Centro Izquierda 16 4
## Centro 7 1
## Centro Derecha 15 3
## Derecha 18 0
Volviendo a la revisión del output de una prueba t de muestras independientes, es importante notar un par
de aspectos más técnicos.
t.test(estudio2012$intolsex~estudio2012$generof)
##
## Welch Two Sample t-test
##
## data: estudio2012$intolsex by estudio2012$generof
## t = 2.5, df = 65, p-value = 0.02
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## 0.1401 1.2920
## sample estimates:
## mean in group Mujer mean in group Hombre
## 2.392 1.676
El título de esta prueba indica que se realizó una prueba t de Welch. Esto es porque las varianzas de los
grupos no son iguales, y R automáticamente realiza el ajuste apropiado. Para forzar una prueba t clásica se
puede agregar el argumento
t.test(estudio2012$intolsex~estudio2012$generof,
var.equal=TRUE)
##
## Two Sample t-test
##
## data: estudio2012$intolsex by estudio2012$generof
## t = 2.1, df = 110, p-value = 0.04
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## 0.03124 1.40086
## sample estimates:
## mean in group Mujer mean in group Hombre
## 2.392 1.676
que indica que deben asumirse varianzas iguales. Esto no es recomendado, ¡para eso existe este ajuste!

61
Otro detalle es que esta función realiza por defecto un contraste de hipótesis bilateral. En caso de que se
quiera hacer un contraste unilateral, pueden ocupar el argumento:
t.test(estudio2012$intolsex~estudio2012$generof,
alternative="greater")
##
## Welch Two Sample t-test
##
## data: estudio2012$intolsex by estudio2012$generof
## t = 2.5, df = 65, p-value = 0.008
## alternative hypothesis: true difference in means is greater than 0
## 95 percent confidence interval:
## 0.2349 Inf
## sample estimates:
## mean in group Mujer mean in group Hombre
## 2.392 1.676
Pero incluso aunque quieran hacer un contraste unilateral esto no es necesario, la probabilidad asociada a la
hipótesis nula en un contraste unilateral es simplemente la mitad de la probabilidad obtenida en un contraste
bilateral.

Prueba t para muestras dependientes: Comparar el promedio poblacional de dos variables en


un grupo.

Para realizar una prueba t para muestras dependientes simplemente hay que agregar un argumento a la
función t.test(): paired=TRUE.
Esta prueba asume que las variables efectivamente son comparables, lo que no siempre es cierto. En este
estudio, la escala de empatía frente al aborto parece adecuada, ya que los participantes tenían que contestar
la misma pregunta pero referida a distintas situaciones:
“Imagina que una mujer recientemente tuvo un aborto y te relata su experiencia. ¿Qué tanto puedes empatizar
con ella en las siguientes situaciones?” (desde 1 = nada, hasta 7 = mucho).
Las situaciones presentadas fueron las siguientes:
abor1 Mi embarazo era un riesgo grave para mi salud.
abor2 Mi hijo hubiese nacido con una enfermedad genética grave que lo condenaba a sufrir.
abor3 Fui víctima de violación, tenerlo hubiera sido un recuerdo constante de mi experiencia traumática.
abor4 Por razones económicas era incapaz de hacerme cargo de un hijo, no hubiese podido abastecerlo ni en
sus necesidades más básicas.
abor5 Hubiera sido una madre soltera, estigmatizada por el resto de mi vida.
En general, los niveles de empatía reportados disminuyen progresivamente:
with(estudio2012,
describe(data.frame(abor1, abor2, abor3, abor4, abor5)))
## vars n mean sd median trimmed mad min max range skew kurtosis
## abor1 1 111 5.26 1.83 6 5.51 1.48 1 7 6 -0.81 -0.51
## abor2 2 111 4.60 2.01 5 4.75 2.97 1 7 6 -0.49 -1.01
## abor3 3 110 4.85 2.07 5 5.05 2.97 1 7 6 -0.50 -1.14
## abor4 4 111 3.08 1.95 3 2.90 2.97 1 7 6 0.51 -1.03
## abor5 5 111 2.03 1.40 1 1.76 0.00 1 7 6 1.38 1.15
## se
## abor1 0.17
## abor2 0.19

62
## abor3 0.20
## abor4 0.19
## abor5 0.13
Dado que es la misma escala para cada situación, podemos comparar dos de ellas con una prueba t de
muestras dependientes. Por ejemplo, ¿Produce más empatía una situación de riesgo grave para la salud de la
madre que una situación donde se encuentra una enfermedad genética grave en el hijo(a)?
t.test(estudio2012$abor1, estudio2012$abor2,
paired=TRUE)
##
## Paired t-test
##
## data: estudio2012$abor1 and estudio2012$abor2
## t = 4, df = 110, p-value = 1e-04
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## 0.3294 0.9859
## sample estimates:
## mean of the differences
## 0.6577
Sí, al menos en esta población. La probabilidad de obtener una diferencia mayor o igual a ésta si los promedios
fueran iguales en la población es menor a .05, por lo que podemos rechazar la hipótesis nula.

ANOVA Simple: Comparación de los promedios de múltiples grupos.

Para comparar los promedios de más de dos grupos es necesario hacer un análisis de varianza. La función
para hacer esto en R es aov(). Para estos análisis, vamos a ocupar la escala de intuición:
intui1 Muchas veces tengo muy claro la decisión que voy a tomar, aunque no podría explicar por qué.
intui2 A veces siento que puedo predecir lo que va a pasar antes de que suceda, como por ejemplo que me
llamará alguien.
intui3 Siento que puedo saber cómo es una persona casi inmediatamente, incluso antes de conversar con ella.
intui4 Si en una prueba o examen de alternativas no me acuerdo de la materia, muchas veces puedo elegir de
forma intuitiva, porque “algo” me dice que es la respuesta correcta.
intui5 Para cosas realmente importantes, confío más en mis sentimientos e intuición que en argumentos
racionales.
alpha(with(estudio2012,
data.frame(intui1, intui2, intui3, intui4, intui5)))
##
## Reliability analysis
## Call: alpha(x = with(estudio2012, data.frame(intui1, intui2, intui3,
## intui4, intui5)))
##
## raw_alpha std.alpha G6(smc) average_r S/N ase mean sd
## 0.67 0.67 0.63 0.29 2.1 0.049 3.8 1.1
##
## lower alpha upper 95% confidence boundaries
## 0.57 0.67 0.77
##
## Reliability if an item is dropped:
## raw_alpha std.alpha G6(smc) average_r S/N alpha se
## intui1 0.67 0.68 0.62 0.34 2.1 0.050

63
## intui2 0.60 0.60 0.54 0.28 1.5 0.062
## intui3 0.58 0.59 0.52 0.26 1.4 0.064
## intui4 0.61 0.61 0.55 0.28 1.6 0.060
## intui5 0.62 0.63 0.57 0.30 1.7 0.059
##
## Item statistics
## n raw.r std.r r.cor r.drop mean sd
## intui1 111 0.57 0.57 0.37 0.30 4.1 1.7
## intui2 110 0.72 0.69 0.57 0.46 3.4 1.9
## intui3 111 0.70 0.71 0.62 0.51 3.7 1.6
## intui4 110 0.65 0.68 0.55 0.44 3.7 1.5
## intui5 111 0.64 0.65 0.51 0.42 3.9 1.6
##
## Non missing response frequency for each item
## 1 2 3 4 5 6 7 miss
## intui1 0.07 0.15 0.14 0.16 0.24 0.14 0.09 0.01
## intui2 0.24 0.19 0.12 0.05 0.24 0.12 0.05 0.02
## intui3 0.08 0.18 0.19 0.21 0.23 0.08 0.04 0.01
## intui4 0.06 0.20 0.21 0.21 0.19 0.09 0.04 0.02
## intui5 0.07 0.14 0.19 0.25 0.18 0.11 0.05 0.01
Parece mejor eliminar el ítem 1.
estudio2012$intui = with(estudio2012,
rowMeans(data.frame(intui2, intui3, intui4, intui5),
na.rm=TRUE))
¿Está relacionada la intuición con el signo zodiacal? Primero tenemos que preparar la variable zodiaco.
table(estudio2012$zodiaco)
##
## ...
## 2
## Acuario (21 Enero - 19 Febrero)
## 8
## Aries (21 Marzo - 20 Abril)
## 7
## Cancer (21 Junio - 22 Julio)
## 10
## Capricornio (22 Diciembre - 20 Enero)
## 8
## Escorpion (24 Octubre - 21 Noviembre)
## 7
## Geminis (21 Mayo - 20 Junio)
## 9
## Leo (23 Julio - 22 Agosto)
## 7
## Libra (23 Septiembre - 23 Octubre)
## 11
## Piscis (20 Febrero - 20 Marzo)
## 12
## Sagitario (22 Noviembre - 21 Diciembre)
## 10
## Tauro (21 Abril - 20 Mayo)
## 12

64
## Virgo (23 Agosto - 22 Septiembre)
## 9
estudio2012$zodiacof = factor(estudio2012$zodiaco,
levels=c("Acuario (21 Enero - 19 Febrero)",
"Piscis (20 Febrero - 20 Marzo)",
"Aries (21 Marzo - 20 Abril)",
"Tauro (21 Abril - 20 Mayo)",
"Geminis (21 Mayo - 20 Junio)",
"Cancer (21 Junio - 22 Julio)",
"Leo (23 Julio - 22 Agosto)",
"Virgo (23 Agosto - 22 Septiembre)",
"Libra (23 Septiembre - 23 Octubre)",
"Escorpion (24 Octubre - 21 Noviembre)",
"Sagitario (22 Noviembre - 21 Diciembre)",
"Capricornio (22 Diciembre - 20 Enero)"),
labels=c("Acuario",
"Piscis",
"Aries",
"Tauro",
"Geminis",
"Cancer",
"Leo",
"Virgo",
"Libra",
"Escorpion",
"Sagitario",
"Capricornio"))

table(estudio2012$zodiacof)
##
## Acuario Piscis Aries Tauro Geminis Cancer
## 8 12 7 12 9 10
## Leo Virgo Libra Escorpion Sagitario Capricornio
## 7 9 11 7 10 8
Ahora podemos hacer un ANOVA para ver si el signo zodiacal está relacionado con los niveles de intuición.
Ejecutar simplemente,
aov(intui~zodiacof, data=estudio2012)
## Call:
## aov(formula = intui ~ zodiacof, data = estudio2012)
##
## Terms:
## zodiacof Residuals
## Sum of Squares 17.54 135.98
## Deg. of Freedom 11 98
##
## Residual standard error: 1.178
## Estimated effects may be unbalanced
## 2 observations deleted due to missingness
nos entrega una tabla con la suma de cuadrados y los grados de libertad, lo que no es suficiente información.
Para este análisis, es absolutamente necesario asignar el resultado a un objeto, que vamos a llamar “aov”

65
(podemos poner cualquier nombre).
aov = aov(intui~zodiacof, data=estudio2012)
Ahora podemos ocupar la función summary() para ver el resultado de este análisis.
summary(aov)
## Df Sum Sq Mean Sq F value Pr(>F)
## zodiacof 11 17.5 1.59 1.15 0.33
## Residuals 98 136.0 1.39
## 2 observations deleted due to missingness
En base a los resultados del ANOVA, podemos concluir que no existe una relación entre el signo zodiacal y
los niveles de intuición (F (11, 98) = 1.15, p = .33). Pero es importante notar que los n de cada grupo son
bajos para este análisis. Si vemos la información descriptiva,
boxplot(intui~zodiacof, data=estudio2012)
6
5
4
3
2
1

Acuario Aries Geminis Leo Libra Sagitario


Los participantes del signo Cáncer son los que reportan mayores niveles de intuición, lo que es consistente
con la descripción entregada en http://www.astrology-online.com/cancer.htm
De acuerdo a Astro Lady, en todo caso, Cáncer, Escorpión y Picis son los signos más intuitivos (asociados al
agua). ver http://answers.yahoo.com/question/index?qid=20080124235717AAdSk0S Esto no parece cumplirse
en esta muestra.
Quizás la intuición está relacionada con la mención que quieren elegir los alumnos de psicología. . .
table(estudio2012$mencion)
##
## Clinica Comunitaria
## 4 65 5
## De la salud Educacional Laboral/Organizacional
## 3 13 22
Dado que desgraciadamente hay muy pocas personas que reportan estar interesados en psicología comunitaria
o psicología de la salud, vamos a sacarlos del análisis.
estudio2012$mencionf = factor(estudio2012$mencion,
levels=c("Clinica",

66
"Educacional",
"Laboral/Organizacional"))
Ahora podemos hacer el ANOVA
aov = aov(intui~mencionf, data=estudio2012)
summary(aov)
## Df Sum Sq Mean Sq F value Pr(>F)
## mencionf 2 10.7 5.37 3.91 0.023 *
## Residuals 97 133.2 1.37
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 12 observations deleted due to missingness
Esta vez, los resultados sí son estadísticamente significativos. Pero, ¿qué grupos son diferentes de cuáles? La
información descriptiva
boxplot(intui~mencionf, data=estudio2012)
6
5
4
3
2
1

Clinica Educacional Laboral/Organizacional


parece indicar que las personas que quieren tomar psicología organizacional reportan un menor nivel de
intuición. Para evaluar qué grupos presentan diferencias estadísticamente significativas es necesario hacer un
test de Tukey, ocupando la función TukeyHSD(), que requiere el resultado de un análisis de varianza.
TukeyHSD(aov)
## Tukey multiple comparisons of means
## 95% family-wise confidence level
##
## Fit: aov(formula = intui ~ mencionf, data = estudio2012)
##
## $mencionf
## diff lwr upr p adj
## Educacional-Clinica 0.07051 -0.7771 0.9181 0.9786
## Laboral/Organizacional-Clinica -0.77710 -1.4652 -0.0890 0.0228
## Laboral/Organizacional-Educacional -0.84761 -1.8235 0.1283 0.1021
Al hacer las comparaciones entre estos grupos, vemos que la única diferencia estadísticamente significativa es
la comparación entre los alumnos que quieren especializarse en clínica y los alumnos que quieren especializarse

67
en psicología organizacional. Los alumnos interesados en clínica reportan mayores niveles de intuición que los
interesados en organizacional (p = .02).
Uno de los supuestos del ANOVA es que las varianzas de los grupos son iguales. Para evaluar si se cumple este
supuesto, pueden hacer una prueba de levene ocupando la función levene.test() de la librería lawstat:
#install.packages("lawstat")
library(lawstat)

levene.test(estudio2012$intui, estudio2012$mencionf)
##
## modified robust Brown-Forsythe Levene-type test based on the
## absolute deviations from the median
##
## data: estudio2012$intui
## Test Statistic = 0.011, p-value = 0.9
En este caso, la prueba no es estadísticamente significativa, por lo que podemos asumir que las varianzas de
los grupos en la población efectivamente son iguales. Si las varianzas fueran diferentes, corresponde hacer un
ANOVA de Welch, que no asume varianzas iguales:
oneway.test(intui~mencionf, data=estudio2012)
##
## One-way analysis of means (not assuming equal variances)
##
## data: intui and mencionf
## F = 3.6, num df = 2, denom df = 29, p-value = 0.04
Estos resultados se reportan así: F de Welch (2, 28.63) = 3.56, p = .04.
Desgraciadamente, R no incluye por defecto el R2 en el output de ANOVA. para obtenerlo, podemos ocupar
la función summary.lm() en el objeto que creamos para el análisis.
summary.lm(aov) # ver al final, "Adjusted R-squared": 0.06
##
## Call:
## aov(formula = intui ~ mencionf, data = estudio2012)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.6218 -0.8447 -0.0947 0.8782 2.4053
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.8718 0.1454 26.63 <2e-16 ***
## mencionfEducacional 0.0705 0.3561 0.20 0.8434
## mencionfLaboral/Organizacional -0.7771 0.2891 -2.69 0.0085 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.17 on 97 degrees of freedom
## (12 observations deleted due to missingness)
## Multiple R-squared: 0.0745, Adjusted R-squared: 0.0555
## F-statistic: 3.91 on 2 and 97 DF, p-value: 0.0234
En este caso, la mención preferida explica aproximadamente un 6% de la varianza en intuición.

68
ANOVA Factorial: Relación entre una variable numérica y múltiples variables
categóricas.

La función aov() también permite agregar más de una variable categórica, y evaluar la interacción entre estas
variables, utilizando el formato aov(variable dependiente ~ factor1 * factor2). Sería ideal tener más
n del que tenemos en este estudio, especialmente para evaluar la interacción entre los dos factores, pero vamos
a ver un ejemplo de todas formas, agregando género al análisis que acabamos de hacer.
Hagamos primero un gráfico para ver los descriptivos.
with(estudio2012,
interaction.plot(generof, mencionf, intui))
4.0

mencionf
Clinica
Laboral/Organizacional
3.5
mean of intui

Educacional
3.0
2.5
2.0

Mujer Hombre

generof
Y ahora el análisis de varianza.
aov = aov(intui~mencionf*generof, data=estudio2012)
summary(aov)
## Df Sum Sq Mean Sq F value Pr(>F)
## mencionf 2 10.3 5.17 3.92 0.023 *
## generof 1 6.9 6.86 5.19 0.025 *
## mencionf:generof 2 2.4 1.18 0.89 0.413
## Residuals 93 122.7 1.32
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 13 observations deleted due to missingness
Si bien al parecer el género tiene un efecto más grande en los estudiantes interesados en psicología educacional,
la interacción entre estos dos factores no es estadísticamente significativa. En cambio, hay un efecto principal
de género, donde los hombres reportan menos intuición que las mujeres (F (1,93) = 6.86, p = .03), y de
mención, donde las personas interesadas en especializarse en organizacional reportan menores niveles de
intuición (F (2,93) = 10.34, p = .02).
También pueden pedir los descriptivos para cada factor y sus interacciones con model.tables(), lo que
además tiene la ventaja de que incluye el n de cada grupo (rep). ¡Solamente una de las personas que está

69
interesada en psicología educacional es hombre!
model.tables(aov, "means")
## Tables of means
## Grand mean
##
## 3.697
##
## mencionf
## Clinica Educacional Laboral/Organizacional
## 3.854 3.942 3.095
## rep 64.000 13.000 22.000
##
## generof
## Mujer Hombre
## 3.846 3.256
## rep 74.000 25.000
##
## mencionf:generof
## generof
## mencionf Mujer Hombre
## Clinica 3.96 3.50
## rep 49.00 15.00
## Educacional 4.10 2.00
## rep 12.00 1.00
## Laboral/Organizacional 3.38 2.68
## rep 13.00 9.00
Ahora el test de Tukey va a incluir comparaciones múltiples para género, para mención y también para la
interacción entre estos dos factores, aunque típicamente las comparaciones uno a uno entre las combinaciones
de factores no se reportan.
TukeyHSD(aov)
## Tukey multiple comparisons of means
## 95% family-wise confidence level
##
## Fit: aov(formula = intui ~ mencionf * generof, data = estudio2012)
##
## $mencionf
## diff lwr upr p adj
## Educacional-Clinica 0.08814 -0.7443 0.92056 0.9656
## Laboral/Organizacional-Clinica -0.75947 -1.4357 -0.08322 0.0238
## Laboral/Organizacional-Educacional -0.84761 -1.8048 0.10960 0.0935
##
## $generof
## diff lwr upr p adj
## Hombre-Mujer -0.5899 -1.118 -0.06218 0.0289
##
## $`mencionf:generof`
## diff lwr
## Educacional:Mujer-Clinica:Mujer 0.1416 -0.9352
## Laboral/Organizacional:Mujer-Clinica:Mujer -0.5780 -1.6209
## Clinica:Hombre-Clinica:Mujer -0.4626 -1.4491
## Educacional:Hombre-Clinica:Mujer -1.9626 -5.3396

70
## Laboral/Organizacional:Hombre-Clinica:Mujer -1.2867 -2.4990
## Laboral/Organizacional:Mujer-Educacional:Mujer -0.7196 -2.0578
## Clinica:Hombre-Educacional:Mujer -0.6042 -1.8989
## Educacional:Hombre-Educacional:Mujer -2.1042 -5.5837
## Laboral/Organizacional:Hombre-Educacional:Mujer -1.4282 -2.9024
## Clinica:Hombre-Laboral/Organizacional:Mujer 0.1154 -1.1514
## Educacional:Hombre-Laboral/Organizacional:Mujer -1.3846 -4.8538
## Laboral/Organizacional:Hombre-Laboral/Organizacional:Mujer -0.7087 -2.1583
## Educacional:Hombre-Clinica:Hombre -1.5000 -4.9527
## Laboral/Organizacional:Hombre-Clinica:Hombre -0.8241 -2.2336
## Laboral/Organizacional:Hombre-Educacional:Hombre 0.6759 -2.8479
## upr p adj
## Educacional:Mujer-Clinica:Mujer 1.21834 0.9989
## Laboral/Organizacional:Mujer-Clinica:Mujer 0.46499 0.5924
## Clinica:Hombre-Clinica:Mujer 0.52389 0.7479
## Educacional:Hombre-Clinica:Mujer 1.41439 0.5410
## Laboral/Organizacional:Hombre-Clinica:Mujer -0.07429 0.0308
## Laboral/Organizacional:Mujer-Educacional:Mujer 0.61873 0.6237
## Clinica:Hombre-Educacional:Mujer 0.69059 0.7517
## Educacional:Hombre-Educacional:Mujer 1.37538 0.4966
## Laboral/Organizacional:Hombre-Educacional:Mujer 0.04590 0.0632
## Clinica:Hombre-Laboral/Organizacional:Mujer 1.38217 0.9998
## Educacional:Hombre-Laboral/Organizacional:Mujer 2.08462 0.8538
## Laboral/Organizacional:Hombre-Laboral/Organizacional:Mujer 0.74095 0.7133
## Educacional:Hombre-Clinica:Hombre 1.95267 0.8035
## Laboral/Organizacional:Hombre-Clinica:Hombre 0.58547 0.5345
## Laboral/Organizacional:Hombre-Educacional:Hombre 4.19980 0.9934
Para hacer un anova con múltiples factores sin incluir sus interacciones, basta reemplazar el signo * por un +.
aov = aov(intui~mencionf+generof, data=estudio2012)
summary(aov)
## Df Sum Sq Mean Sq F value Pr(>F)
## mencionf 2 10.3 5.17 3.93 0.023 *
## generof 1 6.9 6.86 5.21 0.025 *
## Residuals 95 125.1 1.32
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 13 observations deleted due to missingness
El anova simple con mención explicaba un 6% de la varianza en los niveles de intuición. Al incluir género el
nivel de varianza explicada es ahora un 9%.
summary.lm(aov)
##
## Call:
## aov(formula = intui ~ mencionf + generof, data = estudio2012)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.750 -0.745 -0.128 0.750 2.372
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.99993 0.15702 25.47 <2e-16 ***

71
## mencionfEducacional -0.00978 0.35173 -0.03 0.978
## mencionfLaboral/Organizacional -0.65081 0.28757 -2.26 0.026 *
## generofHombre -0.62191 0.27256 -2.28 0.025 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.15 on 95 degrees of freedom
## (13 observations deleted due to missingness)
## Multiple R-squared: 0.121, Adjusted R-squared: 0.0931
## F-statistic: 4.35 on 3 and 95 DF, p-value: 0.00642

ANCOVA

Para hacer un ancova y controlar estadísticamente por el efecto de una variable continua, simplemente puede
agregarse esta variable como predictor en la función aov(), con +, ya que normalmente no nos interesan sus
interacciones.

Relaciones entre variables lineales.

Prueba estadística para correlaciones.

En la sección de descriptivos, vimos que era posible obtener el coeficiente de correlación entre dos variables
continuas con la función cor():
cor(estudio2012$insom, estudio2012$cinsom,
use = "pairwise.complete.obs")
## [1] 0.3545
Para saber si esta correlación es estadísticamente significativa, la función que hay que ocupar es
cor.test(estudio2012$insom, estudio2012$cinsom)
##
## Pearson's product-moment correlation
##
## data: estudio2012$insom and estudio2012$cinsom
## t = 4, df = 110, p-value = 1e-04
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## 0.1800 0.5074
## sample estimates:
## cor
## 0.3545
Esta función no requiere especificar que deben omitirse los participantes con NA, por lo que probablemente
es más práctica que cor() para obtener una correlación. Aún así, la gracia de cor() es que permite hacer
una matriz de correlaciones, lo que no es posible con cor.test().
El output de esta prueba nos entrega la significación estadística (r = .35, p < .001), y también un intervalo
de confianza para la correlación. En este caso, entre .18 y .51.
Al igual que en una prueba t (de hecho esto es una prueba t) podemos hacer una hipótesis unilateral o bilateral.
En caso de que tengan una hipótesis unilateral, simplemente tienen que agregar alternative="greater" (o
"less") a la función cor.test(). En general esto no es necesario. Simplemente pueden reportar la mitad
de p cuando el contraste es unilateral.

72
cor.test(estudio2012$insom, estudio2012$cinsom,
alternative="greater")
##
## Pearson's product-moment correlation
##
## data: estudio2012$insom and estudio2012$cinsom
## t = 4, df = 110, p-value = 7e-05
## alternative hypothesis: true correlation is greater than 0
## 95 percent confidence interval:
## 0.2092 1.0000
## sample estimates:
## cor
## 0.3545

Correlación parcial

Para calcular una correlación parcial entre x e y, controlando por z, es necesario instalar la librería ppcor,
y ocupar la función pcor.test(). Esta función simplemente no acepta observaciones con NAs, por lo que
vamos a tener que procesar un poco nuestra base de datos. El procedimiento que vamos a ocupar se aplica
a cualquier otra situación en que queramos sacar de una base de datos a las personas que no contestaron
algunas de las variables, así que vale la pena revisarlo de todas formas.
Primero, para simplificar las cosas, vamos a crear una nueva base de datos incluyendo Únicamente las variables
insom, ansev y cinsom; que vamos a llamar corpar.
corpar = with(estudio2012,
data.frame(insom, ansev, cinsom))
Una vez hecho esto, podemos seleccionar Únicamente a las personas que efectivamente tienen puntajes en
estas tres variables, ocupando el argumento “complete.cases”:
corpar = corpar[complete.cases(corpar), ]
Ahora que tenemos una base de datos que no tiene ningún NA,
describe(corpar)
## vars n mean sd median trimmed mad min max range skew kurtosis
## insom 1 110 3.25 1.68 3.00 3.13 1.98 1 7 6 0.47 -0.81
## ansev 2 110 4.41 1.44 4.67 4.42 1.98 1 7 6 -0.09 -0.97
## cinsom 3 110 3.97 1.99 4.00 3.95 2.97 1 7 6 0.05 -1.34
## se
## insom 0.16
## ansev 0.14
## cinsom 0.19
vamos a revisar la correlación entre insomnio y ansiedad ante evaluaciones, controlando por conductas
negativas del sueño.
# install.packages("ppcor") # Primero tenemos que instalar
library(ppcor) # y cargar la librería ppcor
La función pcor.test() ocupa el formato pcor.test(x, y, z), donde z es la variable que queremos
controlar.
with(corpar, pcor.test(insom, ansev, cinsom))
## estimate p.value statistic n gp Method
## 1 0.3845 3.667e-05 4.308 110 1 pearson

73
La correlación se mantiene prácticamente igual al controlar por conductas negativas del sueño, lo que nos
da cierta indicación de que la relación entre insomnio y ansiedad en periodos de evaluaciones no puede ser
explicada por esta variable.

Regresión

Hacer regresión en R es exactamente lo mismo que hacer un ANOVA. De hecho, la función aov() ocupa la
función básica para hacer modelos de regresión: lm(). El formato de esta función es exactamente el mismo:
lm(variable dependiente ~ predictor1 + predictor2).
Una de las escalas que no hemos ocupado es la de estrés universitario, que podemos usar para predecir los
niveles de insomnio. La escala tiene los siguientes ítems:
streu1 Siento que no me alcanza el tiempo para cumplir con todas mis responsabilidades académicas.
streu2 Siento molestias físicas (dolor de cabeza, de estómago, náuseas, etc.) debido a la cantidad de actividades
que debo realizar.
streu3 Siento que tengo tantas responsabilidades académicas que no logro “desconectarme” en mi tiempo
libre.
streu4 Cuando pienso en todas las actividades que tengo que hacer me pongo irritable.
streu5 Siento mucha presión para cumplir con todas mis responsabilidades en la universidad.
La confiabilidad es buena,
alpha(with(estudio2012,
data.frame(streu1, streu2, streu3, streu4, streu5)))
##
## Reliability analysis
## Call: alpha(x = with(estudio2012, data.frame(streu1, streu2, streu3,
## streu4, streu5)))
##
## raw_alpha std.alpha G6(smc) average_r S/N ase mean sd
## 0.83 0.83 0.83 0.5 5 0.025 4.5 1.4
##
## lower alpha upper 95% confidence boundaries
## 0.79 0.83 0.88
##
## Reliability if an item is dropped:
## raw_alpha std.alpha G6(smc) average_r S/N alpha se
## streu1 0.86 0.86 0.85 0.60 6.0 0.022
## streu2 0.79 0.79 0.76 0.48 3.7 0.032
## streu3 0.78 0.78 0.76 0.47 3.6 0.034
## streu4 0.77 0.77 0.75 0.46 3.4 0.034
## streu5 0.79 0.79 0.76 0.48 3.7 0.032
##
## Item statistics
## n raw.r std.r r.cor r.drop mean sd
## streu1 112 0.60 0.61 0.44 0.41 5.0 1.7
## streu2 112 0.81 0.80 0.76 0.68 3.9 1.9
## streu3 112 0.82 0.81 0.77 0.69 4.1 2.0
## streu4 112 0.83 0.84 0.80 0.73 4.5 1.8
## streu5 112 0.80 0.80 0.76 0.68 4.8 1.8
##
## Non missing response frequency for each item
## 1 2 3 4 5 6 7 miss
## streu1 0.01 0.12 0.07 0.15 0.20 0.18 0.27 0

74
## streu2 0.12 0.19 0.12 0.15 0.21 0.09 0.12 0
## streu3 0.11 0.21 0.11 0.12 0.13 0.19 0.13 0
## streu4 0.06 0.12 0.11 0.13 0.24 0.17 0.16 0
## streu5 0.05 0.09 0.08 0.19 0.17 0.21 0.21 0
y aunque eliminar el primer ítem mejoraría un poco el alpha, la correlación del ítem con el total es adecuada
(.4), por lo que prefiero incluirlo de todas formas.
estudio2012$streu = with(estudio2012,
rowMeans(data.frame(streu1, streu2, streu3, streu4, streu5),
na.rm=TRUE))

hist(estudio2012$streu, breaks=7)
abline(v=mean(estudio2012$streu, na.rm=TRUE), col="red")
Histogram of estudio2012$streu
25
20
Frequency

15
10
5
0

1 2 3 4 5 6 7

estudio2012$streu
Noten que el promedio está claramente por sobre el punto medio de la escala.
¿Podemos predecir los niveles de insomnio a partir de los niveles de estrés universitario reportados por los
participantes? La función lm() funciona igual que aov(), y también es necesario asignar el resultado a un
objeto, que ahora vamos a llamar lm.
lm = lm(insom~streu, data=estudio2012)
summary(lm)
##
## Call:
## lm(formula = insom ~ streu, data = estudio2012)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.795 -1.343 -0.378 1.032 3.664
##

75
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.710 0.504 3.39 0.00096 ***
## streu 0.347 0.107 3.24 0.00160 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.61 on 109 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.0877, Adjusted R-squared: 0.0793
## F-statistic: 10.5 on 1 and 109 DF, p-value: 0.0016
El resultado de este análisis indica que efectivamente los niveles de estrés universitario predicen los niveles de
insomnio de forma significativa. El output entrega los coeficientes no estandarizados: un punto en la escala
de estrés se asocia (en general) a un aumento de .35 puntos en la escala de insomnio.
Como vimos en la sección de descriptivos, el resultado de este análisis puede ser ocupado para dibujar la
línea de regresión sobre un dispersiograma que muestra la relación entre las variables.
plot(estudio2012$streu, estudio2012$insom)
abline(lm(insom~streu, data=estudio2012), col="red")
7
6
estudio2012$insom

5
4
3
2
1

2 3 4 5 6 7

estudio2012$streu
lm() no entrega los coeficientes estandarizados. Pero es tremendamente fácil hacerlo ocupando la función
scale().
z = scale(estudio2012$streu) # convierte a puntajes z
describe(z) # con promedio 0 y desviación estándar 1
## vars n mean sd median trimmed mad min max range skew kurtosis
## X1 1 112 0 1 0.03 0.01 1.14 -2.14 1.77 3.91 -0.12 -0.93
## se
## X1 0.09
scale() puede ser ocupado directamente dentro del modelo de regresión para obtener los coeficientes
estandarizados.

76
lmz = lm(scale(insom)~scale(streu), data=estudio2012)
summary(lmz)
##
## Call:
## lm(formula = scale(insom) ~ scale(streu), data = estudio2012)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.664 -0.799 -0.225 0.614 2.181
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.00272 0.09108 -0.03 0.9762
## scale(streu) 0.29618 0.09151 3.24 0.0016 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.96 on 109 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.0877, Adjusted R-squared: 0.0793
## F-statistic: 10.5 on 1 and 109 DF, p-value: 0.0016

Regresión múltiple

Para hacer una regresión múltiple, simplemente hay que agregar otros predictores ocupando + (a no ser que
quieran evaluar también la interacción entre dos predictores).
lm = lm(insom~streu+ansev+intui, data=estudio2012)
summary(lm)
##
## Call:
## lm(formula = insom ~ streu + ansev + intui, data = estudio2012)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.814 -1.014 -0.257 0.986 3.714
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.9994 0.6544 1.53 0.1297
## streu 0.0675 0.1355 0.50 0.6195
## ansev 0.4295 0.1347 3.19 0.0019 **
## intui 0.0155 0.1271 0.12 0.9029
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.56 on 106 degrees of freedom
## (2 observations deleted due to missingness)
## Multiple R-squared: 0.166, Adjusted R-squared: 0.143
## F-statistic: 7.06 on 3 and 106 DF, p-value: 0.000227
Al incluir ansiedad en periodo de evaluaciones el efecto de estrés universitario deja de ser significativo, y -como
es esperable- los niveles de intuición no predicen los niveles de insomnio. Es perfectamente posible entender

77
ansiedad en periodo de evaluaciones como un mediador del efecto de estrés universitario en insomnio. La
idea es que las personas pueden tener más o menos estrés universitario (streu), por ejemplo porque tomaron
muchos ramos, y esto genera problemas de sueño (insom) justamente porque disminuye la capacidad de
enfrentar tranquilamente los periodos de evaluaciones (ansev).
Una forma de evaluar mediación es haciendo tres regresiones, mostrando que
1. La variable independiente predice la variable dependiente.
lm1 = lm(insom~streu, data=estudio2012)
summary(lm1)
##
## Call:
## lm(formula = insom ~ streu, data = estudio2012)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.795 -1.343 -0.378 1.032 3.664
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.710 0.504 3.39 0.00096 ***
## streu 0.347 0.107 3.24 0.00160 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.61 on 109 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.0877, Adjusted R-squared: 0.0793
## F-statistic: 10.5 on 1 and 109 DF, p-value: 0.0016
2. La variable independiente predice el mediador.
lm2 = lm(ansev~streu, data=estudio2012)
summary(lm2)
##
## Call:
## lm(formula = ansev ~ streu, data = estudio2012)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.638 -0.805 -0.178 0.884 2.570
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.6412 0.3499 4.69 7.9e-06 ***
## streu 0.6242 0.0748 8.34 2.5e-13 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.13 on 109 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.39, Adjusted R-squared: 0.384
## F-statistic: 69.6 on 1 and 109 DF, p-value: 2.46e-13
3. El efecto de la variable independiente deja de ser significativo al incluir el mediador.

78
lm3 = lm(insom~ansev+streu, data=estudio2012)
summary(lm3)
##
## Call:
## lm(formula = insom ~ ansev + streu, data = estudio2012)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.805 -1.024 -0.267 0.975 3.682
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.0463 0.5277 1.98 0.0500 *
## ansev 0.4300 0.1340 3.21 0.0018 **
## streu 0.0692 0.1342 0.52 0.6069
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.55 on 107 degrees of freedom
## (2 observations deleted due to missingness)
## Multiple R-squared: 0.166, Adjusted R-squared: 0.151
## F-statistic: 10.7 on 2 and 107 DF, p-value: 5.91e-05
También es posible que el efecto de la variable independiente siga siendo significativo, pero se observe una
reducción importante. Las librerías QuantPsyc y Lavaan incluyen funciones para análisis más sofisticados de
mediación.

Interacciones entre variables continuas

Incluir interacciones en ecuaciones de regresión es prácticamente igual que en ANOVAs, con la diferencia de
que los predictores tienen que estar centrados. Es decir, su promedio debe ser 0 (hay excepciones pero creo
que es una buena regla general). Una forma fácil de hacer esto es ocupar puntajes estandarizados.
A modo de ejemplo, vamos a incluir la interacción entre estrés universitario y conductas negativas del sueño.
Quizás el estrés universitario afecta menos a las personas que evitan ver televisión hasta tarde.
Ahora el modelo de regresión incluye un * en vez de un +, para incluir la interacción entre los dos predictores
ya centrados.
lm = lm(scale(insom)~scale(streu)*scale(cinsom), data=estudio2012)
summary(lm)
##
## Call:
## lm(formula = scale(insom) ~ scale(streu) * scale(cinsom), data = estudio2012)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.8279 -0.5876 -0.0515 0.4915 2.5550
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.0106 0.0891 0.12 0.90519
## scale(streu) 0.2297 0.0897 2.56 0.01187 *
## scale(cinsom) 0.3059 0.0897 3.41 0.00092 ***

79
## scale(streu):scale(cinsom) -0.0591 0.0861 -0.69 0.49390
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.918 on 107 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.18, Adjusted R-squared: 0.157
## F-statistic: 7.81 on 3 and 107 DF, p-value: 9.21e-05
Como es esperable, las conductas asociadas a baja calidad del sueño predicen los niveles de insomnio. Pero la
interacción entre estrés universitario y estas conductas no es estadísticamente significativa.

Regresiones y ANOVA

En R, el hecho de que las regresiones lineales y los ANOVA son lo mismo es explícito: aov() simplemente hace
un modelo ocupando lm() y lo reporta como es tradicional en los análisis de varianza. De hecho, tanto aov()
como lm() permiten agregar predictores numéricos o categóricos. En el caso de las variables categóricas, R
automáticamente crea las variables dicotómicas que sean necesarias. La consecuencia práctica que tiene esto
es que pueden agregar tranquilamente predictores categóricos a lm() y predictores numéricos a aov().
Por ejemplo, podemos pedir el siguiente modelo, donde se incluyen genero y situación sentimental como
predictores de insomnio.
lm = lm(insom~streu+ansev+ # Predictores numéricos
generof+sitsentf, # Predictores categóricos
data=estudio2012)
El output de
summary(lm)
##
## Call:
## lm(formula = insom ~ streu + ansev + generof + sitsentf, data = estudio2012)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.681 -1.070 -0.254 1.003 3.643
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.9648 0.5650 1.71 0.0907 .
## streu 0.0386 0.1386 0.28 0.7815
## ansev 0.4502 0.1392 3.23 0.0016 **
## generofHombre 0.1312 0.3582 0.37 0.7150
## sitsentfEs complicado 0.7555 0.6103 1.24 0.2186
## sitsentfSoltero/a 0.0340 0.3160 0.11 0.9145
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.56 on 102 degrees of freedom
## (4 observations deleted due to missingness)
## Multiple R-squared: 0.174, Adjusted R-squared: 0.134
## F-statistic: 4.31 on 5 and 102 DF, p-value: 0.00135
muestra que el único predictor significativo de insomnio es ansiedad en periodos de evaluaciones. También se
observa ser hombre predice mayores niveles de insomnio, pero el efecto no es significativo. Además estar tener

80
una situación sentimental “complicada” (vs. “En una relación”) predice mayores niveles de insomnio, pero
nuevamente el efecto no es estadísticamente significativo, posiblemente porque hay muy pocos participantes
que reportan su situación sentimental como complicada.
FIN
Lo que hemos revisado debiera ser más que suficiente para la mayoría de los análisis que se realizan típicamente
en psicología. Los anexos incluyen un poco más de información en caso de que alguna vez la necesiten.

ANEXOS
La libreria ggplot2 es un excelente recurso para hacer gráficos más sofisticados o con mejores opciones de
presentación.
# install.packages("ggplot2")
library(ggplot2)
qplot(bfext, bfopen, data=personalidad, geom = c("point", "smooth"))

180

150
bfopen

120

90

0 50 100 150
bfext
Es posible que dos librerías cargadas tengan funciones con el mismo nombre pero que hacen cosas diferentes. Por
ejemplo, la función alpha() de la librería psych calcula el alpha de Cronbach, pero modifica la transparencia
de un color en ggplot2.
En estos casos, puede especificarse la librería con el formato
psych::alpha()
Y también es útil re-definir una función con la librería que prefieran en caso de que vayan a ocuparla
frecuentemente

81
alpha = psych::alpha
en caso de que quisieran ocupar la otra, todavía pueden escribir ggplot2::alpha().
Al comienzo del tutorial, les recomendé que guardaran el espacio de trabajo automáticamente al cerrar el
programa. Especialmente cuando están trabajando en muchos proyectos, es útil guardar los espacios de
trabajo (con todos los objetos) en archivos separados, que pueden ser cargados en cualquier momento.
ls() # Mostrar el espacio de trabajo actual
save.image("estudio2012.RData") # Guardar espacio de trabajo
load("Liberia.Rdata") # Cargar espacio de trabajo
rm(list=ls()) # Eliminar todos los objetos en el espacio de trabajo

Otras funciones útiles:

Para buscar información.


help(mean) # también puede escribirse como
?mean # y agregar dos ?? permite buscar en la documentación online de R
# por palabras clave. Por ejemplo,
??mean
??"mean center"
Para combinar bases de datos en base a una variable (identificador) común:
help(merge)
El lugar donde aparecen los gráficos puede dividirse para incluir varios gráficos en la misma imagen
par(mfrow=c(1,2)) # Divide el output gráfico en dos columnas.
hist(estudio2012$intolsex)
boxplot(estudio2012$intolsex)

Histogram of estudio2012$intolsex
7
60

6
50

5
Frequency

40

4
30

3
20
10

2
0

1 2 3 4 5 6 7

estudio2012$intolsex

82
par(mfrow=c(1,1)) # Quita la división del output gráfico.

Otros análisis estadísticos

Para modelos de ecuaciones estructurales (SEM) pueden ocupar la librería lavaan. Ver más información en
http://lavaan.ugent.be
Para modelos multinivel pueden ocupar la librería lme4, específicamente la función lmer().

83

También podría gustarte