Recuerda que tenemos diversos posts y dictamos cursos de programación, pesquerías, ecología, entre otros. Te invitamos a revisar la lista completa de nuestros posts en nuestra sección Posts y suscribirte a nuestras redes en Facebook y X para enterarte de nuestros cursos y de sus aperturas próximas.
En Excel
Para este artículo, utilizaremos como ejemplo el archivo mtcars.xlsx
El primer paso será seleccionar toda las celdas con las que deseamos trabajar, luego buscar el botón de Tabla Dinámica (Pivot Table) en la pestaña Insertar:
Se abrirá una ventana que nos pedirá confirmación de la selección de celdas y si deseamos mostrar los resultados en una nueva hoja. Dejaremos todo como nos lo sugiere y solo daremos click en Aceptar:
A continuación, se abrirá una nueva hoja con una barra lateral a la derecha que nos permitirá seleccionar las columnas con las que deseamos realiza nuestro análisis.
Para nuestro primer ejemplo, solicitaremos que nos calcule el promedio para las variables mpg y wt, utilizando los valores de am y gear como variables de agrupación. Para ello, tendremos que arrastrar dichas variables a los campos de Valores y Filas, respectivamente.
Posteriormente, tendremos que hacer click en cada una de las variables en la sección de Valores y seleccionar la opción Configuración del campo de valor (Value Field Settings)
Se abrirá una pequeña ventana mostrándonos todos los estadísticos disponibles. Seleccionaremos la opción de Promedio (Average) y daremos click en Aceptar. Repetiremos esto para la otra variable.
Y así, después de muchos clicks, tenemos nuestra primera tabla dinámica:
Luego, utilizando las opciones en la pestaña de Diseño, podemos ocultar los subtotales.
En R
Veremos ahora cómo replicar el ejemplo anterior en R a través de dos enfoques:
Utilizando funciones de R base
mtcars es un objeto que viene precargado en R, por lo que no será necesario cargarlo desde Excel. Sin embargo, puedes encontrar los detalles de cómo leer archivos de Excel en R en nuestro artículo ¿Cómo cargar (leer) una tabla de Excel en R?.
# Mostrar el número de filas y columnas (en ese orden) de mtcarsdim(mtcars)
[1] 32 11
# Mostrar las primeras 10 filas de mtcarshead(mtcars, 10)
Utilizaremos la función aggregate, cuya sintaxis indica que el primer argumento deberá contener la tabla con los valores que deseamos reorganizar (en nuestro caso, un subset de mtcars indicando únicamente las columnas mpg y wt). Luego, en el argumento by indicaremos a modo de lista las variables que nos servirán como agrupadoras (en nuestro ejemplo am y gear). Finalmente, con el argumento FUNle indicaremos qué estadístico deseamos aplicar sobre los valores agrupados (en nuestro caso mean, que calcula el promedio de valores numéricos).
aggregate(x = mtcars[,c("mpg", "wt")], by =list(mtcars$am, mtcars$gear), FUN = mean)
¡Y eso es todo! Podemos verificar que hemos obtenido los mismos valores que con el análisis en Excel. Es posible modificar los nombres de columnas de las variables agrupadoras a través del nombre dado en la lista usada para el argumento by de la siguiente manera:
aggregate(x = mtcars[,c("mpg", "wt")], by =list(am = mtcars$am, gear = mtcars$gear), FUN = mean)
Así mismo, desde R podemos ejecutar una amplia variedad de funciones, algunas de ellas no están disponibles en la ventana que nos abre Excel. Por ejemplo, la mediana:
aggregate(x = mtcars[,c("mpg", "wt")], by =list(am = mtcars$am, gear = mtcars$gear), FUN = median)
El entorno de tidyverse (que involucra un conjunto de paquetes y herramientas orientadas al manejo optimizado de tablas de datos) se ha hecho muy popular en los últimos años, por lo que es importante mostrar qué nos ofrece respecto a Tablas dinámicas.
Dentro del paquete dplyr, utilizaremos las funciones group_by y summarise:
require(dplyr)mtcars |># Definir las variables de agrupación separadas por comasgroup_by(am, gear) |># Ejecutar las operaciones para cada variablesummarise(mpg =mean(mpg),wt =mean(wt), .groups ="drop") # .groups cierra la orden de agrupación
Observamos que los resultados son los mismos que los obtenidos con Excel y con aggregate. Sin embargo, ¿cómo aplicar una misma función a lo largo de todo un conjunto de variables? Existen varios modos, uno de ellos es añadiendo la función across.
require(dplyr)mtcars |># Definir las variables de agrupación separadas por comasgroup_by(am, gear) |># Ejecutar las operaciones para cada variablesummarise(across(.cols =c(mpg, wt), .fns = mean), .groups ="drop")
¿Por qué se muestran menos valores decimales al utilizar summarise?
A primera impresión, podría parecer que el proceso ha quitado decimales a nuestro cálculo; sin embargo, esto es solo la manera en cómo un objeto de clase tbl_df/tbl se muestra en consola. Por ejemplo, digamos que creamos un data frame de la siguiente manera:
Podemos observar que el método print aplicado a un objeto de clase data.frame muestra todos los valores decimales. No obstante, al convertirlo a un objeto de clase tbl_df/tbl, el print en consola solo mostrará un pequeño número de decimales, pero esto se hará SIN modificar nuestra tabla original. En otras palabras, el método print de un objeto tbl_df/tbl hará un redondeo de los valores con decimales UNICAMENTE al momento de mostrar la tabla en consola.
# A tibble: 3 × 2
a b
<dbl> <chr>
1 15.1 A
2 2.77 B
3 -5.99 C
Podemos verificar de dos maneras que los valores se mantienen:
A través de la función all.equal que solamente devuelve TRUE cuando los dos objetos ingresados son exactamente iguales.
all.equal(target = df_ejemplo$a, current = tbl_ejemplo$a)
[1] TRUE
Realizando una diferencia entre las columnas de ambas tablas y observando que todos los valores son iguales a cero.
df_ejemplo$a - tbl_ejemplo$a
[1] 0 0 0
En este último ejemplo, vemos que a través del argumento .cols de across definimos las variables con los valores que ingresarán al cálculo, mientras que con .fns definimos la función (o funciones) que deseamos ejecutar. Y sí, podemos solicitar más de una función en un mismo comando:
require(dplyr)mtcars |># Definir las variables de agrupación separadas por comasgroup_by(am, gear) |># Ejecutar las operaciones para cada variablesummarise(across(.cols =c(mpg, wt), .fns =list(promedio = mean, mediana = median)), .groups ="drop")