1 INTRODUCCIÓN

La organización de los datos constituye la primera etapa en el tratamiento y análisis de cualquier estudio estadístico. Las tablas son un modo habitual de organización y presentación de los resultados, si bien con el desarrollo de los medios informáticos ha perdido la relevancia de tiempos anteriores.

Una tabla consiste en una ordenación, asignando a cada valor/valores su frecuencia (número de veces qué aparece) agrupada en clases o categorías mutuamente excluyentes.

Su elaboración require:

2 COMPONENTES DE UNA TABLA DE FRECUENCIAS

Las tablas de frecuencias están compuestas básicamente por los siguientes elementos:

Si además nuestros datos poseen un orden interno, las tablas pueden incluir:

3 TIPOS DE TABLAS DE FRECUENCIA

La naturaleza de los datos (atributos, variables), es decir, el número de valores distintos y el número de observaciones influyen en el tipo de tabla de frecuencias. Podemos considerar dos tipos de tablas de frecuencia:

3.1 TABLAS DE FRECUENCIA CON DATOS NO AGRUPADOS

Son apropiadas para el análisis de variables cualitativas o variables cuantitativas discretas. En el caso de variable cualitativas nominales, las tablas estadísticas suelen incluir cuántos valores diferentes aparecen (su frecuencia absoluta) y qué fracción del total representan (la frecuencia relativa).

3.1.1 Variable cualitativa nominal.

Para ilustrar la elaboración de una tabla de frecuencias con datos no agrupados sobre una variable cualitativa nominal, se creará un vector con la función sample(), que generará un conjunto de datos aleatorios con reemplazo (argumento replace=TRUEes decir, se pueden repetir) en forma de caracteres (que corresponden a los niveles), con un tamaño específico (size=100) y una probabilidad de aparición. En este caso, tenemos 3 niveles o categorías (\(k\)=3) y 100 observaciones (\(n\)=100)

Figura 1: Tabla variable cualitativa nominal

datos1 <- sample(c("María", "Pedro","Jaime"),       # Caracteres a reproducir 
                 size = 100,                        # Número de caracteres
                 replace = TRUE,                    # Se pueden repetir
                 prob=c(0.5,0.3,0.2))               # Probabilidades de aparición

La tabla con las frecuencias absolutas se obtiene con la función table(). La función devuelve una tabla unidimensional con dos filas, una con los niveles de la variable y otra con su frecuencia absoluta.

table(datos1)

La tabla de frecuencias relativas se calcula anidando la función prop.table() a la tabla calculada previamente, ¡no al vector original!. Su estructura es análoga a la tabla anterior.

prop.table(table(datos1))

Si convertimos esas tablas en vectores, podemos unirlos en una única tabla con la función cbind(), que puede visualizarse con View().

datos1_ni <- table(datos1)
datos1_fi <- prop.table(table(datos1))
tabla1 <- cbind(datos1_ni, datos1_fi)          
View(tabla1)

Desafío

Calcula las frecuencias relativas y absolutas de la variable (atributo) barrio del dataframe zonas_verdes. Recuerda que para llamar a una variable concreta de un dataframe utilizamos la sintaxis nombre_dataframe$nombre_variable.

3.1.2 Variable cualitativa ordinal

Las variables cualitativas ordinales, en este caso los resultados de una encuesta en la que se ha preguntado a los clientes de un supermercado si están de acuerdo en el cobro de una tasa por el uso de bolsas de plastico, tienen un orden natural (“escala de tipo Likert). Esto permite acumular observaciones, es decir, contar cuántas hay por debajo de un nivel, mediante el cálculo de las frecuencias acumuladas.

Figura 2: Tabla variable cualitativa ordinal

Como paso previo a la elaboración de la tabla, se crea un vector con los datos de la encuesta.

datos2 <- sample(c("1_Totalmente de acuerdo", "2_De acuerdo con matices","3_No estoy seguro","4_En desacuerdo con matices","5_Totalmente en desacuerdo"), 
                 size = 100, 
                 replace = TRUE, 
                 prob=c(0.22,0.3,0.2,0.15,0.13))

El procedimiento de elaboración de este tipo de tabla es análogo al visto en el apartado anterior. Primero se crean los vectores que corresponden a las frecuencias absolutas y relativas, a las que se añadirán los vectores correspondientes a las frecuencias absolutas acumuladas y relativas acumuladas. Todos estos vectores se unirán finalmente en una única tabla.

  • Las frecuencias absolutas se obtienen con la función table().
datos2_ni <- table(datos2)
datos2_ni
  • Las frecuencias absolutas acumuladas se calculan anidando la función cumsum() a la tabla anterior. Estas frecuencias acumuladas informan de cuántas veces hemos observado un dato menor o igual que él.
datos2_Ni <- cumsum(table(datos2))                              
datos2_Ni
  • Las frecuencias relativas se calculan anidando la función prop.table() a la tabla calculada previamente.
datos2_fi <- prop.table(table(datos2))                            
datos2_fi
  • Finalmente, las frecuencias relativas acumuladas se obtienen anidando la función cumsum a prop.tabley a table. Equivale a la fracción del total de estudiantes que representa su frecuencia absoluta acumulada.
datos2_Fi <- cumsum(prop.table(table(datos2)))                    
datos2_Fi

Finalmente, podemos crear una única tabla juntando todos los vectores anteriores

tabla2 <- cbind(datos2_ni,datos2_fi,datos2_Ni,datos2_Fi)          
View(tabla2)

Para mejorar la presentación de la tabla tabla2, conviene cambiar los nombres de las variables a otros más legibles.

colnames(tabla2) <- c("ni","fi","Ni","Fi")
View(tabla2)

Desafío

Calcula las frecuencias absolutas acumuladas y relativas acumuladas de la variable barrio del dataframe zonas_verdes, y crea una tabla denominada tabla_barrios añadiendo las frecuencias absoluta y relativa. Cambia los nombres de las variables de la tabla a

3.1.3 Variable cuantitativa

Para tabular una variable cuantitativa sin agrupar los datos se calculan las frecuencias absolutas y absolutas acumuladas, como en las variables ordinales, puesto que podemos ordenarla siguiendo el orden natural de los números reales. Como ejemplo vamos a considerar la temperatura máxima diaria medida en el observatorio de Reinosa durante el mes de julio de 2023.

Figura 3: Tabla variable cuantitativa discreta

Los datos originales se crean como un vector:

datos3 <- c(32,31,28,29,33,32,31,30,31,31,27,28,29,30,32,31,31,30,30,29,29,30,30,31,30,31,34,33,33,29,29)

A continuación se procede al cálculo de las diferentes frecuencias:

datos3_ni <- table(datos3)                                        # Frecuencias absolutas
datos3_Ni <- cumsum(table(datos3))                                # Frecuencias absolutas acumuladas
datos3_fi <- prop.table(table(datos3))                            # Frecuencias relativas 
datos3_Fi <- cumsum(prop.table(table(datos3)))                    # Frecuencias relativas acumuladas

Para crear una columna en la tabla con las etiquetas correspondientes a los valores originales procedemos de esta manera:

datos3_min <- min(datos3)
datos3_max <- max(datos3)
Valores_tem <- min(datos3):max(datos3)

A continuación se crea la tabla

tabla3 <- cbind(Valores_tem, datos3_ni,datos3_fi,datos3_Ni,datos3_Fi)          # Tabla con todas las frecuencias (4 columnas)

colnames(tabla3) <- c("ni","fi","Ni","Fi")

View(tabla3)

Una vez realizado el ejemplo, o bien podemos borra todos los objetos que figuran en el Global Environment, o bien grabarlos como un

#rm(list=ls())
#save.image("tablas_frecuencias.RData")

Desafío

Crea una tabla que comprenda todos los elementos con la variable parques del dataframe zonas_verdes.

3.2 TABLAS DE FRECUENCIAS CON DATOS AGRUPADOS.

Cuando el número de observaciones numéricas de una variable es muy elevado (variables cuantitativas discretas) o analizamos una variable cuantitativa continua es habitual agrupar el campo de variación en intervalos de clase. Cada clase o categoría no incluye un único valor sino un conjunto de valores (\(a_i\)).

Cada una de estas clases tiene dos límites de clase \(L_{i1}-L_i\) , el superior (\(L_{i1}\)) y el inferior (\(Li\)).

La diferencia entre ambos límites se conoce como intervalo de clase y cada clase está representada por un único valor o marca de clase \(x_i\)

El proceso para su elaboración es el siguiente:

  • Decidir el número de intervalos o categorías.

  • Calcular la amplitud de cada intervalo.

  • Obtener los extremos de los intervalos.

  • Establecer las marcas de clase.

Supongamos que el vector datos4 contiene una variable continua que hemos redondeado en unidades enteras.

datos4 <- c(3,15,24,28,33,35,38,42,43,38,36,34,29,25,17,7,34,36,39,44,31,26,20,11,13,22,27,47,39,37,34,32,35,28,38,41,48,15,32,13)

Figura 4: Tabla variable cuantitativa discreta

3.2.1 Paso 1: elección del número de clases

Podemos decidir el número de clases \(k\) de acuerdo a criterios subjetivos, o recurrir a procedimientos más objetivos para orientar la elección. Las más populares son las siguientes:

  • Regla de Nordcliffe o de la raíz cuadrada: \(k=\big\lceil \sqrt{n}\big\rceil\).

  • Regla de Sturges: \(k= \big\lceil 1+\log_{2}(n)\big\rceil.\)

  • Regla de Scott: Se determina primero la amplitud teórica \(A_S\) de las clases mediante la fórmula \[ A_S= 3.5\cdot \widetilde{s}\cdot n^{-\frac{1}{3}} \] (donde \(\widetilde{s}\) es la desviación típica del conjunto de datos), y entonces se toma \[ k=\left\lceil\frac{\max(x) -\min(x)}{A_S}\right\rceil. \]

  • Regla de Freedman-Diaconis: Se determina primero la amplitud teórica \(A_{FD}\) de las clases por medio de la fórmula \[ A_{FD}= 2 \cdot (Q_{0.75}-Q_{0.25}) \cdot n^{-\frac{1}{3}} \] (siendo \(Q_{0.75}-Q_{0.25}\) el rango intercuartílico), y entonces se toma de nuevo \[ k= \left\lceil \frac{\max(x) -\min(x)}{A_{FD}}\right\rceil.\]

Las dos primeras sólo dependen del número de casos \(n\), mientras que las dos últimas tienen en cuenta también su dispersión. No hay una regla mejor que las otras, es habitual la repetición del mismo procedimiento con métodos diferentes para poder revelar fenómenos diversos.

En primer lugar, implementaremos estos criterios manualmente; los tres últimos también están implementadas en R a través de las funciones nclass.Sturges(), nclass.scott() y nclass.FD().

  • OPCIÓN 1: implementación manual
N <- length(datos4)                      

norcliffe <- ceiling(sqrt(N))                # Criterio de Norcliffe (raíz cuadrada)
sturgess <- ceiling(1+log(N,2))              # Criterio de Sturgess

# Criterio de Scott
As <- 3.5*sd(datos4)*N^(-1/3)                # Amplitud teórica
scott <- ceiling(diff(range(datos4))/As)
scott

# Criterio de Freedman-Diaconis
Afd <- 2*(quantile(datos4,0.75, names = FALSE)-quantile(datos4,0.25,names = FALSE))*N^(-1/3) 
diaconis <- ceiling(diff(range(datos4))/Afd)
diaconis
  • OPCIÓN 2: podemos comprobar la bondad de nuestros cálculos requiriendo a R las funciones correspondientes (puede haber ligeras diferencias en los resultados con respecto a los obtenidos manualmente).
nclass.Sturges(datos4)
nclass.scott(datos4)
nclass.FD(datos4)

El número de clases elegido será 6.

k <- 6

3.2.2 Paso 2: Cálculo de la amplitud de los intervalos.

Uno vez calculado el número de intervalos (\(k\)), podemos obtener su amplitud. Ello requiere a su vez calcular el rango (\(R\), que es la diferencia entre el valor más alto y el valor más bajo), y dividirlo posteriormente por el número de clases \(k\).

Figura 5: Cálculo de la amplitud de los intervalos clases

El rango se calcula anidando la función diff() sobre la función range() (esta última proporciona el valor mínimo y el valor máximo de nuestros datos).

range(datos4)

a <- round(diff(range(datos4)) / k)
a

3.2.3 Paso 3: cálculo de los extremos de cada clase.

Para ello necesitamos saber, inicialmente, el valor mínimo de los datos que manejamos.

L1 <- min(datos4)-1/2                 
L1

Posteriormente, se crearán 7 límites (que corresponden a 6 clases). Se pueden obtener mediante dos procedimientos:

  • OPCIÓN 1: es el más recomendable. De forma iterativa multiplica la amplitud con cada una de las 7 límites (0:6) y posteriormente suma el límite inferior.
L <- L1 + a*(0:6)                     

L
  • OPCIÓN 2: un ejemplo similar, desarrollado paso a paso.
L2 <- L1 + a
L3 <- L2 + a
L4 <- L3 + a
L5 <- L4 + a
L6 <- L5 + a
L7 <- L6 + a
Lbis <- c(L1,L2,L3,L4,L5,L6,L7)

Lbis                                             # Son los límites de clase

3.2.4 Paso 4: Cálculo de las marcas de clase

A partir de los límites de clase, podemos calcular la marca de cada clase (en realidad, el teórico punto medio).

Figura 6: Cálculo de la amplitud de los intervalos clases

Como en el caso anterior, podemos calcularlos a través de dos procedimientos.

  • OPCIÓN 1: de nuevo el más recomendable. El procedimiento se inicia calculando la primera marca, como valor medio de los límites inferior y superior de la primera clase, y posteriormente, de forma iterativa se multiplica la amplitud con cada una de las 6 clases (0:5) y posteriormente suma la primer marca.
X1 <- (L[1]+L[2])/2
X <- X1 + a*(0:5)                           
X
  • OPCIÓN 2. Ejemplo desarrollado.
X1 <- (L[1]+L[2])/2
X1
X2 <- X1 + a
X3 <- X2 + a
X4 <- X3 + a
X5 <- X4 + a
X6 <- X5 + a
X <- c(X1,X2,X3,X4,X5,X6)
X

3.2.5 Paso 5: Recuento del número de valores dentro de cada clase o categoría.

En realidad, hasta este momento, lo único que ha sido definido realmente es el número de categorías o clases, y las etiquetas de esas categorias, es decir, la columna encabezada por \(L_{i1}-Li\). En esta última, los límites pueden aparecer precedidos o seguidos de un corchete [] o de un paréntesis ()).

  • Un corchete al principio (final) indica que el primer (último) número está incluido dentro de ese intervalo. Se considera entonces un intervalo cerrado.

  • Un paréntesis al principio (final) indica que el primer (último) número está excluido de ese intervalo. Se considera entonces un intervalo abierto.

Ejemplo:

  • (3,8) no incluye ni el 3 ni el 8 (pero si 4, 5, 6, 7).

  • [3,8] incluye el 3 y el 8, además de los intermedios.

  • (3,8] incluye al 8, pero no al 3 (está abierto por el 3 y cerrado por el 8).

  • [3,8) incluye al 3, pero no al 8 (está cerrado por el 3 y abierto por el 8).

Figura 7: Intervalos abiertos o cerrados

Para rellenar el resto de columas de nuestra tabla es necesario contar el número de veces que los valores originales caen dentro de cada uno de las clases o categorías. Esta tarea la lleva a cabo la función cut(). Su sintaxis básica incluye los siguientes argumentos:

Figura 8: Función cut()

Ejemplos:

  • Partición en intervalos calculados a partir de los definidos en líneas anteriores.
particion <- cut(datos4, 
                   breaks = L, 
                   right = FALSE)
  • Partición en 6 categorías o intervalos (creados por el propio ordenador), cerrados por la izquierda y abiertos por la derecha
particion_2 <- cut(datos4, 
                   breaks = 6, 
                   right = FALSE)
  • Partición en intervalos incorporando directamente los resultados del criterio de Norcliffe (raíz cuadrada del número de casos).
particion_3 <- cut(datos4, 
                   breaks = ceiling(sqrt(length(datos4))), 
                   right = FALSE)
  • Partición en intervalos con etiquetas específicas.
particion_4  <- cut(datos4, 
                    breaks = L, 
                    right = FALSE, 
                    labels = c("Peq", "Norm", "Gran", "XGran", "Gigan","Monst")) # Podemos incluir etiquetas
  • Partición en intervalos creados por el propio investigador.
particion_5 <- cut(datos4, 
                   breaks = c(0,10,20,30,40,50), 
                   right = FALSE, 
                   labels = FALSE)

Se pueden comprobar las etiquetas correspondientes a cada una de esas categorías, mediante la función levels() aplicada al vector particion_1. Igualmente, podemos verificar las marcas de clase.

etiquetas <- levels(particion)                                # Etiquetas con los límites de clase
etiquetas

marcas <- X                                                     # Etiquetas con las marcas de clase
marcas

Al añadir a nuestra base de datos el vector generado por dicha función resulta en en un dataframe con 2 columnas, la primera con los datos originales y la segunda con la clase o categoría a la que pertenece.

datos4 <- cbind(datos4,particion)                     
datos4

3.2.6 Paso 6: Creación de la tabla.

Una vez obtenidas las etiquetas y las marcas de cada categoría, estamos en condiciones de crear la tabla de frecuencias sobre datos agrupados.

¡ATENCIÓN!: en este caso, las funciones table() y prop.table() etc… no pueden aplicarse directamente al factor particion; requiere su transformación en vector.

Repetimos la secuencia de operaciones vista anteriormente.

datos4_ni <- as.vector(table(particion))                      # Frecuencias absolutas
datos4_fi <- as.vector(prop.table(table(particion)))          # Frecuencias relativas

datos4_Ni <- as.vector(cumsum(datos4_ni))                       # Frecuencias absolutas acumuladas
datos4_Fi <- as.vector(cumsum(datos4_fi))                       # Frecuencias relativas acumuladas

tabla4 <- data.frame(etiquetas, 
                     marcas, 
                     datos4_ni,
                     datos4_fi, 
                     datos4_Ni, 
                     datos4_Fi)  
tabla4

También podemos cambiar los nombres de las etiquetas de algunas columnas de nuestra tabla de frecuencias. A continuación se cambiarán los nombres de la 3ª a la 6ª columna.

colnames(tabla4)[3:6] <- c("ni", "fi", "Ni", "Fi")
tabla4

Si quisiéramos recuperar posteriormente esta información, convendría exportar todos los objetos (como imagen del entorno de trabajo)

save.image(file = "tablas_frecuencias.RData")

Desafío

Crea una tabla con la variable superficie del dataframe zonas_verdes, comparando los procedimientos para la obtención del número de clases.

A continuación, se deben salvar los cálculos realizados y posteriormente, eliminar todos los objetos para comenzar una nueva actividad

save.image("tablas_frecuencias.RData")
rm(list=ls())

De vez en cuando, también es conveniente limpiar la consola de órdenes previas.

cat("\014")