options(repos = list(CRAN="http://cran.rstudio.com/"))

Activación de librerias

library(readr)
library(readxl)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(haven)
library(tables)
library(tidyverse)
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v ggplot2 3.3.5     v purrr   0.3.4
## v tibble  3.1.4     v stringr 1.4.0
## v tidyr   1.2.0     v forcats 0.5.1
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(modeest)
## Registered S3 method overwritten by 'rmutil':
##   method         from
##   print.response httr
library(fdth)
## 
## Attaching package: 'fdth'
## The following object is masked from 'package:modeest':
## 
##     mfv
## The following objects are masked from 'package:stats':
## 
##     sd, var
library(e1071)
## 
## Attaching package: 'e1071'
## The following object is masked from 'package:modeest':
## 
##     skewness
library(RcmdrMisc)
## Loading required package: car
## Loading required package: carData
## 
## Attaching package: 'car'
## The following object is masked from 'package:purrr':
## 
##     some
## The following object is masked from 'package:dplyr':
## 
##     recode
## Loading required package: sandwich
library(car)
library(carData)
library(sandwich)

1 Creación de Dataframes

El primer paso en el uso de R para el análisis estadístico es la cración de datos. El dataframe es lo comunmente podemos denominar como una tabla de datos.

Edad <- c(1, 2, 3, 5, 7, 9, 11, 13)
Altura <- c(76.11, 86.45, 95.27, 109.18, 122.03, 133.73, 143.73, 156.41)

Ejemplo1 = data.frame(Edad, Altura)
Ejemplo1 

Ejercicio 1: Cree un data frame en el que se relacionen tres variables distintas empleando 10 datos.

Nota: Para agregar un Chunk en el Script utilizar la combinación de teclas “Ctrl + Alt +i”

¿Qué pasa si las variables son de distintos tipos?

Ejemplo2 <- data.frame(
  "Entero" = 1:4,
  "Factor" =c("a", "b", "c", "d"), 
  "Número" = c(1.2, 3.4, 4.5, 5.6),
  "Cadena" = as.character(c("a", "b", "c", "d"))
  )

Ejemplo2

1.1 Gráfico inicial

Con estos elementos ya podemos crear nuestro primer gráfico:

plot(Edad, Altura)

Y también podemos empezar a crear modelos, como por ejemplo un modelo de regresión lineal simple

mod_regresion_lineal =lm(Altura ~ Edad, data = Ejemplo1)
summary(mod_regresion_lineal)
## 
## Call:
## lm(formula = Altura ~ Edad, data = Ejemplo1)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -4.351 -1.743  0.408  2.018  2.745 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  73.9681     1.7979   41.14 1.38e-08 ***
## Edad          6.4934     0.2374   27.36 1.58e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2.746 on 6 degrees of freedom
## Multiple R-squared:  0.992,  Adjusted R-squared:  0.9907 
## F-statistic: 748.4 on 1 and 6 DF,  p-value: 1.577e-07

2 Importando archivos

En R podemos trabajar con archivos de otros lenguajes los cuales se pueden importar de varias maneras. Utilizando directamente un script que nos permita cargar los archivos utilizamos los siguientes códigos, dependiendo de la fuente de los datos:

2.1 De Excel (Requiere la librería readxl)

Paises <- read_excel("Paises.xlsx")
View(Paises)

2.2 De internet

Por ejemplo la dirección de internet https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data contiene archivos para hacer Machine Learning

download.file(
  url = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data", 
  destfile = "iris.data"
  )

2.3 De SPSS (Requiere la librería haven)

Agresividad <- read_sav("Agresividad.sav")
View(Agresividad)

2.4 De un archivo CSV (Requiere la libería readr)

ejemplo <- read_csv("ejemplo.csv")
## Rows: 10 Columns: 5
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr (1): country
## dbl (4): wos, scopus, total, percentage
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.
View(ejemplo)

La otra forma es directamente de las opciones Import Dataset o del menú File – Import Dataset.

3 Filtrado de data frames

En muchos casos interesa visualizar algunas partes del data frame y hacer filtrado de los datos. Esto se puede hacer con varios comandos básicos:

  1. head(data frame): Muestra las primeras seis líneas del data frame
  2. tail(data frame): Muestra las últimas seis filas del data frame
  3. names(data frame): Muestra los nombres de las columnas del data frame.
  4. dim(data frame): Muesta las dimensiones del data frame.

Algunos filtros más avanzados se cargan con la libería “dplyr”.

NOTA: El operador %>% denominado pipeline es útil para concatenar variables de un data frame. Se extrae con el conjunto de teclas “Ctrl + Shift + M”.

  1. El comando select selecciona columnas del data frame
Ejemplo3 <- Paises %>% 
  select(pais, continente, pib_per_capita)
Ejemplo3
  1. El comando filter filtra el data frame por un valor específico
Ejemplo4 <- Paises %>% 
  filter(pais == "Brasil")
Ejemplo4

Un filtro más avanzado utilizando los dos comandos anteriores sería

Ejemplo5 <-Paises %>% 
  filter(pais == "Brasil") %>% 
       select(pais, esperanza_de_vida)
Ejemplo5

También se pueden aplicar filtros por condiciones de valor

Ejemplo6 <- Paises %>% 
  filter(esperanza_de_vida > 30) %>% 
       select(pais, anio, esperanza_de_vida, continente)
Ejemplo6
  1. La función group_by que sirve para agrupar conjuntos de filas. Es muy útil cuando se trabaja con la función summarise(), la cual crea un nuevo data frame.
life_expect_by_country <- Paises %>% 
  group_by(pais) %>% 
  summarise(mean_life_expect = mean(esperanza_de_vida))

life_expect_by_country

3.0.1 Ejercicio

Utilice el anterior data frame (life_expect_by_country) para encontrar el mayor país en donde la expectativa de vida media sea mayor.

  1. Función mutate para agregar elementos a un data frame
Ejemplo7 <- Paises %>% 
  filter(anio == 2007) %>% 
  group_by(continente) %>% 
  mutate(pob_total = sum(poblacion)) %>% 
  ungroup()
Ejemplo7

3.0.2 Ejercicio

Utilizando la función mutate agregue una columna al data frame anterior en donde se observe la proporción de la población de un país respecto a la población total del continente donde se ubica dicho país.

4 Disribuciones de frecuencia

Una distribución de frecuencias es una tabla en donde se organizan las distintas frecuencias de un conjunto de datos. Las frecuencias son:

  1. Frecuencia absoluta \(f_i\): Corresponde a la cantidad de veces que aparece un dato en una muestra.

  2. Frecuencia relativa \(h_i\): Corresponde a la proporción entre la \(f_i\) y el tamaño de la muestra \(n\). Su fórmula es \[h_i=\dfrac{f_i}{n}\]

  3. Frecuencias acumuladas \(F_i;H_i\): Corresponde a la suma de las frecuencias que se han acumulado hasta un dato específico.

Para ilustrar la elaboración de estas tablas utilizaremos la base de datos Agresividad de los archivos de trabajo. En este documento debemos codificar dos de las variables que se tienen las cuales corresponden a género (1 = Hombre, 2 = Mujer) y la variable víctima de Bulling (1 = Si; 2 = No). Esto se realiza mediante el siguiente código:

Agresividad <- read_excel("Agresividad.xlsx")
View(Agresividad)
Agresividad$Genero = factor(Agresividad$Genero, levels = c(1, 2),
                            labels = c("Hombre", "Mujer"))
Agresividad$`Victima bullying` = factor(Agresividad$`Victima bullying`, 
                                        levels = c(1, 2),
                                        labels = c("Si", "No"))

A continuación creamos algunas tablas de frecuencias absolutas:

Tabla_1 <- table(Agresividad$Genero)
View(Tabla_1)
Tabla_2 <- table(Agresividad$`Estrato socioecono`)
View(Tabla_2)
Tabla_3 <- table(Agresividad$Grado)
View(Tabla_3)
Tabla_4 <- table(Agresividad$`Victima bullying`)
View(Tabla_4)

También podemos crear tablas con frecuencias relativas utilizando el siguiente código:

Tabla_5 <- prop.table(table(Agresividad$Genero))
View(Tabla_5)
Tabla_6 <- prop.table(table(Agresividad$Grado))
View(Tabla_6)

Ahora bien, para presentar todas las tablas en una sola que corresponda a la distribución de frecuencias podemos utilizar el siguiente código para la distribución de frecuencias de la variable Grado:

Tabla <- as.data.frame(Tabla_3)
Distribucion <- Tabla %>%  
  summarise(Grado = Tabla[,1], f = Tabla_3, F = cumsum(Tabla_3), h = Tabla_6, H = cumsum(Tabla_6))
Distribucion

Ejercicio: Utilizando estos mismos comandos, ¿se podrá realizar el cruce de variables, hallar por ejemplo la cantidad de hombres y mujeres que han sido víctima de bulling?

4.1 Agrupación de datos

En algunos casos, las variables numéricas tienen un rango muy amplio y su distribución de frecuencias absolutas es de valores muy pequeños. En estos casos se suele utilizar el proceso de agrupación de datos por intervalos o clases. Una forma de realizar esto es mediante el procedimiento que se aplica en el siguiente código en donde se utiliza la función fdt de la librería fdth.

Dist_Edad <- fdt(Agresividad$Edad, breaks = "Sturges")
Dist_Edad
##     Class limits  f   rf rf(%)  cf  cf(%)
##   [10.89,11.588) 26 0.12 11.76  26  11.76
##  [11.588,12.286) 47 0.21 21.27  73  33.03
##  [12.286,12.983)  0 0.00  0.00  73  33.03
##  [12.983,13.681) 52 0.24 23.53 125  56.56
##  [13.681,14.379) 29 0.13 13.12 154  69.68
##  [14.379,15.077) 30 0.14 13.57 184  83.26
##  [15.077,15.774)  0 0.00  0.00 184  83.26
##  [15.774,16.472) 24 0.11 10.86 208  94.12
##   [16.472,17.17) 13 0.06  5.88 221 100.00

Con este comando también personalizar la amplitud de los intervalos agregando el punto inicial y el final de los intervalos \(fdt(x, start= a, end = b, h = c)\). Incluso podemos establecer el número de clases que se quieren construir \(fdt(x, k=a)\).

5 Representaciones gráficas

En estadística, la visualización de datos es una de las formas más importantes que se tiene para comprender de primera mano un conjunto de datos. Las funcionalidades gráficas de R son muy variadas y versátiles y a partir de las distintas librerías y paquetes se pueden crear gráficos muy sofisticados. En este curso utilizaremos las funciones básicas de una de las librerías más completas para estas tareas que se conoce como ggplot2. A continuación presentaremos algunos ejemplos:

Agresividad %>% 
  ggplot()+aes(x = Edad)+
  geom_bar()

Agresividad %>% 
  ggplot(aes(x = Genero, y = Edad, fill = Genero))+
  geom_boxplot()+ geom_jitter(width=0.1,alpha=0.2)

Paises %>% 
  ggplot(aes(x= continente, y=esperanza_de_vida, fill=continente)) +
  geom_boxplot() +
  geom_jitter(width=0.1,alpha=0.2) +
  xlab("Continent")+ 
  facet_wrap(~anio) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

6 Medidas numéricas

Las medidas numéricas en estadística descriptiva pueden ser de varios tipos:

6.1 Medidas de tendencia central.

Como su nombre lo indica, son medidas que se utilizan para identificar la tendencia de la concentración central de los datos. Estas son moda, media y mediana (con algunas de sus variantes).

6.1.1 Media

Es una medida que calcula la suma total de los datos dividida entre el tamaño de la muestra:

\[ \bar{x}=\sum_{i=1}^n \dfrac{x_i}{n} \]

El comando básico para calcular la media es mean(x, na.rm = FALSE) donde x representa el conjunto de datos y la opción na.rm = FALSE es un valor lógico que elimina o conserva los valores na que se encuentren en el data frame.

mean(Agresividad$Edad, na.rm = FALSE)
## [1] 13.51584

En algunos casos se pueden calcular medidas por grupos de variables. Por ejemplo, si queremos calcular la media en la edad de los casos de la muestra diferenciados por género podemos utilizar la función split que divide los datos y la función sapply que permite iterar los resultados en cada una de las categorías de la variable considerada.

sapply(split(x = Agresividad$Edad, f = Agresividad$Genero), mean)
##   Hombre    Mujer 
## 13.53922 13.49580

Media ponderada

En algunos casos, se requiere ponderar o “pesar” para darle cierto valor relativo respecto a los demás datos de la muestra. En estos casos, la media ponderada se calcula así:

\[ \bar{x}_p=\dfrac{\sum{x_i\cdot w_i}}{\sum w_i} \]

Donde cada \(w_i\) representa los pesos o ponderaciones. Consideremos por ejemplo el caso de las notas en cuatro exámenes en donde el primero y el tercero representan el 40% de la nota final cada uno y el segundo y el cuarto el 10% cada uno. Si un estudiante obtuvo como notas 4, 2.5, 3 y 2, respectivamente para los parciales 1 a 4, ¿cuál será su nota final?

not <- c(4, 2.5, 3, 2)
w <- c(0.4, 0.1, 0.4, 0.1)
weighted.mean(not, w)
## [1] 3.25

Ejercicio: ¿Cómo realizar el mismo ejercicio anterior de manera directa sin utilizar el comando weighted.mean?

6.1.2 Mediana

La mediana es una medida de localización que ubica el dato que representa al 50% de la muestra.

El comando para hallar la mediana es median(x, na.rm = FALSE) que recibe los mismos argumentos que la función mean.

Ejercicio: Realice un histograma de frecuencia para la variable Edad del conjunto de datos de Agresividad. Elabore también un diagrama de caja para esta misma variable. Con base en estas gráficas responder:

  1. ¿Que se puede decir a simple vista de la simetría de la gráfica en el histograma de frecuencias?

  2. Al calcular la mediana en la variable Edad, ¿cómo relacionamos este resultado con el diagrama de caja?

  3. ¿Qué nos va revelando el diagrama de caja respecto a la asimetría o simetría de una muestra?

6.1.3 Moda o el modo

Esta es la única medida que se puede aplicar a variables cualitativas. Corresponde al dato de mayor frecuencia en la muestra. Se calcula con la función mfv de la librería modeest.

mfv(Agresividad$Edad)
## [1] 13

¿Qué relación existe entre la moda, la media y la mediana?

Empíricamente podemos analizar la forma en cómo están organizados los datos de una muestra (su distribución) analizando las medidas de tendencia central. Cuando las tres medidas son aproximadamente iguales entre sí podemos conjeturar que los datos se distribuyen de manera normal o que se aproximan a una distribución normal.

En el siguiente ejemplo calcularemos las medidas de tendencia central para una muestra que se aproxima a una distribución normal:

set.seed(1234)
x <- rnorm(1000)

Con esto se ha generado un data set que contiene un conjunto de datos que se aproximan a una distribución normal. Analicemos un poco este conjunto de datos para ver como se comporta. En primer lugar observemos la forma de su histograma junto con la línea de densidad.

hist(x, freq = FALSE)
dx <- density(x)
lines(dx$x, dx$y, col = 3, lwd = 1)

Calculemos la moda, media y mediana para ver como se comportan en este conjunto de datos:

mean(x)
## [1] -0.0265972
median(x)
## [1] -0.03979419
mlv(x, method = "hsm")
## [1] -0.03997065

Ejercicio: Dibujar un diagrama de caja para esta variable y elaborar una conclusión a partir de los resultados obtenidos en los dos ejemplos anteriores.

6.2 Cuartiles, deciles y percentiles (Cuantiles)

Dentro del grupo de medidas de localización existen los cuantiles, cantiles o fractiles que ubican un valor que representa una fracción de los datos.

6.2.1 Cuartiles

Los cuartiles \(Q_k\) corresponden a los tres valores que dividen la muestra en cuatro partes iguales cada una equivalente a un 25% de la muestra.

6.2.2 Deciles

Los deciles \(D_k\) corresponden a los nueve valores que dividen la muestra en 10 partes iguales donde cada una agrupa un 10% de los datos.

6.2.3 Percentiles

Los percentiles \(P_k\) corresponden a los 100 valores que dividen la muestra en 100 partes iguales cada una agrupando un 1% de los datos de la muestra. Notamos que los cuantiles o percentiles son el caso general de los deciles y de los percentiles.

  quantile(Agresividad$Edad, probs = c(0.05, 0.1, 0.25, 0.5, 0.75, 0.9))
##  5% 10% 25% 50% 75% 90% 
##  11  11  12  13  15  16

Un resúmen de estas medidas puede obtenerse a partir del comando summary().

summary(object = Agresividad$Edad)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   11.00   12.00   13.00   13.52   15.00   17.00

6.3 Medidas de dispersión o de variabilidad

Las medidas de dispersión son estadísticos descriptivos que permiten establecer que tan homogéneos o heterogéneos son los datos en una muestra. En general nos dan cuenta de que tan alejados están los datos entre sí o de un valor referente como por ejemplo la media.

Las medidas de dispersión son valores de referencia para poder comparar dos o más muestras.

Las medidas de dispersión más comunes son:

  1. Rango: Calcula la diferencia entre los valores extremos de una muestra. Se calcula con la función range(x, na.rm =FALSE).

    \[ R=X_{max}-X_{min} \]

  2. Rango intercuartílico: Da una idea de la concentración de los datos hacia el centro de la distribución. Corresponde a la diferencia entre el tercer y el primer cuartil. Cuando se divide por dos se le conoce como desviación cuartil, siendo útil para distribuciones sesgadas y cuando se toma como referencia la mediana. El rango intercuartílico se calcula directamente con la función IQR(x, na.rm = FALSE).

    \[ DQ=\dfrac{Q_3-Q_1}{2} \]

  3. Varianza: Cuando se considera la media como medida representativa de la muestra (la mayoría de las veces), interesa compararla con cada uno de los datos (lo que no hacen las medidas anteriores). La varianza es una especie de promedio de estas comparaciones en donde la diferencia entre cada dato y la media se eleva al cuadrado para eliminar signos negativos en este resultado y para evitar que la suma final se anule. Se calcula con la función var(x, na.rm = FALSE).

    \[ s^2=\dfrac{\sum(x_i-\bar{x})^2}{n-1};\quad \sigma^2= \dfrac{\sum(x_i-\bar{x})^2}{N} \]

  4. Desviación típica o estándar: Es una medida de dispersión que nos dice que tan alejados se encuentran los datos en relación al promedio y se mide en las mismas unidades en las que se mide la variable de estudio. Se calcula con la función sd(x, na.rm = FALSE).

    \[ s=\sqrt{s^2};\quad \sigma=\sqrt{\sigma^2} \]

Ejercicio: Calcular las medidas de dispersión para la Edad del cuestionario de Agresividad.

Las anteriores medidas se suelen denominar medidas de dispersión absolutas y se caracterizan porque vienen expresadas en las mismas unidades en las que se expresa las variables con las que se calculan. Cuando se quiere relacionar algunas medidas de dispersión con medidas de tendencia central, se obtienen medidas de dispersión relativa, las cuales vienen expresadas en unidades porcentuales y son muy útiles como valores de referencia para comparar dos o más muestras. El más conocido es es el coeficiente de variación o índice de dispersión de Person.

  1. Coeficiente de variación: Expresa la relación entre la media aritmética y la desviación estándar. Se utiliza para comparar datos provenientes de muestras o poblaciones distintas y nos permite tener una medida en donde se elimina la distorsión de las medias entre dos o más poblaciones.

    \[ cv =\dfrac{s}{\bar{x}} \]

    Si consideramos por ejemplo una muestra de elefantes con un peso medio de 5000 kg, una desviación típica de 400 kg y una muestra de ratones con un peso medio de 15 gramos y una desviación típica de 5 gramos. ¿Cómo podemos analizar la dispersión en los pesos de estas dos muestras?

6.4 Medidas de forma.

El grupo de medidas descriptivas se complementa con las medidas de forma, las cuales nos dan una idea de la concentración de los datos hacia la izquierda, derecha o centro de los datos (Asimetría) y el nivel de concentración de los datos en los valores centrales (Curtósis).

Para hallar las medidas de asimetrí y curtósis, utilizamos, respectivamente, los comandos skewness(x, na.rm = TRUE, type =3) y kurtosis(x, na.rm =FALSE, type =3). Estas medidas se ejecutan bajo la librería e1071.

skewness(Agresividad$Edad, na.rm = FALSE, type = 3)
## [1] 0.3737476
kurtosis(Agresividad$Edad, na.rm =FALSE, type =3)
## [1] -0.8864419

6.5 Resúmen de medidas estadísticas

Finalmente conviene tener un resúmen completo de las medidas vistas para tener una idea general de la muestra y de la manera como se organizan los datos.

Nota: Este comando requiere de los paquetes RcmdrMisc, car, carData y sandwich que generalmente vienen integrados con otras librerías pero que se pueden instalar directamente.

numSummary(Agresividad$Edad, statistics=c("mean", "sd", "IQR", "quantiles","cv", "skewness", "kurtosis"), type=c("2", "1", "3"), quantiles=c(0, .25, .5, .75, 1))
##      mean       sd IQR       cv  skewness   kurtosis 0% 25% 50% 75% 100%   n
##  13.51584 1.738854   3 0.128653 0.3788752 -0.8594794 11  12  13  15   17 221