# Calcular resúmenes de datos con dplyr::summarize()

> En este tutorial veremos cómo calcular resúmenes de datos con la función summarize(), que nos permite tomar las filas de una tabla de datos, y aplicarles algún cálculo para reducir todas las filas a un solo dato; por ejemplo, para calcular la suma o el promedio de una columna.

- URL: https://bastianolea.rbind.io/blog/r_introduccion/dplyr_summarize/
- Fecha: 2025-12-14
- Autor: Bastián Olea Herrera
- Etiquetas: dplyr, básico
- Recursos: [Código scraping](https://gist.github.com/bastianolea/c9898df9994cdba32bd6702697498ee589)

---

En el [tutorial de introducción a `{dplyr}`](https://bastianolea.rbind.io/blog/r_introduccion/dplyr_intro/) aprendimos a ordenar, seleccionar, y filtrar datos tabulares. Con estas operaciones básicas deberíamos poder desenvolvernos con tablas de datos.

Luego aprendimos a **crear y modificar variables** con [la función `mutate()` de `{dplyr}`](https://bastianolea.rbind.io/blog/r_introduccion/dplyr_mutate/).

Ahora veremos cómo **calcular resúmenes de datos**. Con esto nos referimos a tomar todas las observaciones o filas de una tabla, y aplicar algún cálculo para **reducir todas las filas a un solo dato**. Esto sirve, por ejemplo, para calcular la suma o el promedio de una columna, y para calcular [estadísticos descriptivos](https://bastianolea.rbind.io/blog/estadisticos_descriptivos/).

``` r
library(dplyr)

options(scipen = 999) # desactivar notación científica
```

> **Aviso:** Si necesitas aprender `{dplyr}` desde el principio, revisa el [tutorial de introducción a `{dplyr}`](https://bastianolea.rbind.io/blog/r_introduccion/dplyr_intro/).

## Introducción

Para este tutorial vamos a trabajar con datos de **población de países de América del Sur**, obtenidas desde [una tabla de Wikipedia](https://es.wikipedia.org/wiki/América_del_Sur#Geografía_política) usando \[web scraping\](https://bastianolea.rbind.io/tags/web-scraping/\]. Puedes ver el [código del web scraping aquí](https://gist.github.com/bastianolea/c9898df9994cdba32bd6702697498ee5).

Para cargar los datos en tu entorno de R, ejecuta el siguiente código:

``` r
datos <- tribble(
                ~pais, ~superficie, ~poblacion,  ~idh,
             "Brasil",     8515767,   2.08e+08, 0.765,
          "Argentina",     2780400,   44500000, 0.845,
               "Perú",     1286216,   32200000, 0.777,
           "Colombia",     1141748,      5e+07, 0.767,
            "Bolivia",     1098581,   11200000, 0.718,
          "Venezuela",      916445,   31800000, 0.711,
              "Chile",      756102,   17800000, 0.851,
           "Paraguay",      406752,    7100000, 0.728,
            "Ecuador",      256370,   16900000, 0.759,
             "Guyana",      214970,      8e+05, 0.682,
            "Uruguay",      176215,    3500000, 0.817,
            "Surinam",      163820,      5e+05, 0.738,
   "Guayana Francesa",       83846,      3e+05, 0.901,
  "Trinidad y Tobago",        5128,    1300000, 0.796
  )
```

Como hemos visto en el [tutorial introductorio de R](https://bastianolea.rbind.io/blog/r_introduccion/r_basico/#funciones), para **calcular una suma** usamos la función `sum()`:

``` r
total <- sum(datos$poblacion)

format(total, big.mark = ".", scientific = FALSE)
```

    [1] "425.900.000"

Mientras que para **calcular un promedio** usamos la función `mean()`:

``` r
promedio <- mean(datos$idh)

round(promedio, 2)
```

    [1] 0.78

Cualquier función como las anteriores, que **reciba varios datos y entregue uno solo**, será una función que podemos usar dentro de `summarize()` para obtener resúmenes de datos.

## Resumir datos con `summarize()`

La función `summarize()` calcula **resúmenes** de las tablas de datos, a partir de una o varias funciones que van a *resumir* los datos a una sola fila.

![](https://bastianolea.rbind.io/blog/r_introduccion/dplyr_summarize/featured.png)

_Esquema de un resumen de datos: se pasa de varias filas a una sola_

Para calcular el resumen de los valores de una variable, dentro de `summarize()` ubicamos la **función** necesaria, aplicada a la **columna** que nos interesa resumir.

Calculemos la suma (`sum()`) de la columna `poblacion`:

``` r
datos |> 
  summarize(
    suma = sum(poblacion)
  )
```

    # A tibble: 1 × 1
           suma
          <dbl>
    1 425900000

Redujimos las 14 filas de nuestra tabla de datos y obtuvimos una sola fila, que resume todos los valores de la `poblacion` a partir de una suma.

Dentro de `summarize()` podemos calcular varios resúmenes al mismo tiempo.

Agreguemos una segunda línea para calcular el **promedio** del índice de desarrollo humano (`idh`):

``` r
datos |> 
  summarize(
    suma = sum(poblacion),
    promedio = mean(idh)
  )
```

    # A tibble: 1 × 2
           suma promedio
          <dbl>    <dbl>
    1 425900000    0.775

### Estadísticos descriptivos

De este modo podemos calcular datos que resumen las observaciones, por ejemplo, [calcular estadísticas descriptivos](https://bastianolea.rbind.io/blog/estadisticos_descriptivos/) relevantes a los datos que estamos trabajando:

``` r
datos |> 
  # calcular estadísticos descriptivos
  summarize(
    poblacion_total = sum(poblacion),
    poblacion_promedio = mean(poblacion),
    poblacion_minima = min(poblacion),
    poblacion_maxima = max(poblacion)
  ) |> 
  # agregar puntos de miles
  mutate(
    across(
      where(is.numeric), ~format(.x, big.mark = ".")
    )
  )
```

    # A tibble: 1 × 4
      poblacion_total poblacion_promedio poblacion_minima poblacion_maxima
      <chr>           <chr>              <chr>            <chr>           
    1 425.900.000     30.421.429         300.000          208.000.000     

> **Nota:** Agregamos un `mutate(across())` para aplicar una función a todas las columnas al mismo tiempo. Para más información, [revisa este tutorial](https://bastianolea.rbind.io/blog/r_introduccion/dplyr_mutate/#crear-varias-columnas-al-mismo-tiempo-con-across).

### Resúmenes por grupos

[Tal que como vimos con `mutate()`](https://bastianolea.rbind.io/blog/r_introduccion/dplyr_mutate/#calcular-variables-por-grupos-con-group_by), podemos anteponer la función de **agrupación** `group_by()` para que los resúmenes de datos se calculen por grupos. Esto significa que, en vez de obtener una sola fila de resumen, obtendremos **una fila por cada grupo** de la variable que elijamos para agrupar los datos.

Primero creemos una variable que nos permita agrupar los datos:

``` r
datos_2 <- datos |>
  # crear grupos por índice de desarrollo humano
  mutate(grupo = case_when(poblacion >= 20000000 ~ "Alta",
                           poblacion >= 5000000 ~ "Media",
                           poblacion <  5000000 ~ "Baja")) |> 
  # ordenar factor
  mutate(grupo = factor(grupo, 
                        levels = c("Baja", "Media", "Alta")))

datos_2 |> 
  count(grupo)
```

    # A tibble: 3 × 2
      grupo     n
      <fct> <int>
    1 Baja      5
    2 Media     4
    3 Alta      5

Ahora, usando `group_by()`, podemos calcular los resúmenes por cada grupo de población:

``` r
datos_2 |> 
  group_by(grupo) |> 
  summarize(
    poblacion_total = sum(poblacion),
    poblacion_promedio = mean(poblacion),
    idh_promedio = mean(idh),
    idh_maximo = max(idh)
  )
```

    # A tibble: 3 × 5
      grupo poblacion_total poblacion_promedio idh_promedio idh_maximo
      <fct>           <dbl>              <dbl>        <dbl>      <dbl>
    1 Baja          6400000            1280000        0.787      0.901
    2 Media        53000000           13250000        0.764      0.851
    3 Alta        366500000           73300000        0.773      0.845

El uso de `group_by()` es muy conveniente, porque podemos tener un mismo código para calcular resúmenes estadísticos, y con tan solo cambiar la variable de agrupación obtendremos resultados actualizados.

### Resúmenes de varias variables con `across()`

En lugar de tener que estar especificando las columnas que queremos resumir, podemos calcular un resumen para varias columnas al mismo tiempo. [Igual que con `mutate()`](https://bastianolea.rbind.io/blog/r_introduccion/dplyr_mutate/#crear-varias-columnas-al-mismo-tiempo-con-across), esto lo logramos usando `across()` dentro de `summarize()`, que permite aplicar las operaciones a varias columnas a la vez.

Por ejemplo, para calcular un resumen de todas las **columnas numéricas**, indicamos dentro de `across()` que queremos aplicar la operación *donde* (`where()`) las variables *sean numéricas* (`is.numeric`):

``` r
datos_2 |> 
  summarize(             # resumir los datos
    across(              # donde las columnas
      where(is.numeric), # sean numéricas
      ~mean(.x)          # calculando el promedio
    )
  )
```

    # A tibble: 1 × 3
      superficie poblacion   idh
           <dbl>     <dbl> <dbl>
    1   1271597. 30421429. 0.775

Para controlar el **nombre** que tendrán las columnas resultantes se puede usar el argumento `.names`:

``` r
datos_2 |> 
  summarise(
    across(where(is.numeric), 
           ~mean(.x), 
           .names = "resumen_{.col}_promedio" # cambiar el nombre de columnas
    )
  )
```

    # A tibble: 1 × 3
      resumen_superficie_promedio resumen_poblacion_promedio resumen_idh_promedio
                            <dbl>                      <dbl>                <dbl>
    1                    1271597.                  30421429.                0.775

O bien, se pueden poner las funciones de resumen dentro de una lista, donde puedes entregarle el nombre que tendrá el resultado:

``` r
datos_2 |> 
  summarise(
    across(where(is.numeric), 
           list(
             "promedio" = ~mean(.x)
           )
    )
  )
```

    # A tibble: 1 × 3
      superficie_promedio poblacion_promedio idh_promedio
                    <dbl>              <dbl>        <dbl>
    1            1271597.          30421429.        0.775

### Múltiples resúmenes a la vez

También es posible calcular resúmenes usando más de una función, por ejemplo para **calcular los promedios y las sumas al mismo tiempo**, entregando las funciones dentro de una lista:

``` r
datos_2 |> 
  summarise(
    across(where(is.numeric), 
           list(
             "promedio" = ~mean(.x), 
             "suma" = ~sum(.x)
           )
    )
  ) |> 
  glimpse()
```

    Rows: 1
    Columns: 6
    $ superficie_promedio <dbl> 1271597
    $ superficie_suma     <dbl> 17802360
    $ poblacion_promedio  <dbl> 30421429
    $ poblacion_suma      <dbl> 425900000
    $ idh_promedio        <dbl> 0.7753571
    $ idh_suma            <dbl> 10.855

O bien, podemos aprovechar `across()` para reducir el código que escribimos en combinación con resúmenes individuales:

``` r
datos_2 |> 
  summarize(
    "idh_prom" = mean(idh),
    across(c(superficie, poblacion), 
           list("suma" = ~sum(.x))
    )
  )
```

    # A tibble: 1 × 3
      idh_prom superficie_suma poblacion_suma
         <dbl>           <dbl>          <dbl>
    1    0.775        17802360      425900000

Obviamente podemos combinar lo anterior con la agrupación para obtener un completo resumen de datos de la tabla:

``` r
datos_2 |> 
  group_by(grupo) |>
  summarise(
    across(where(is.numeric), 
           list(
             "promedio" = ~mean(.x), 
             "suma" = ~sum(.x)
           )
    )
  )
```

    # A tibble: 3 × 7
      grupo superficie_promedio superficie_suma poblacion_promedio poblacion_suma
      <fct>               <dbl>           <dbl>              <dbl>          <dbl>
    1 Baja              128796.          643979            1280000        6400000
    2 Media             629451.         2517805           13250000       53000000
    3 Alta             2928115.        14640576           73300000      366500000
    # ℹ 2 more variables: idh_promedio <dbl>, idh_suma <dbl>
