Creando tablas de resumen

En una hoja de cálculo, las tablas dinámicas o pivot tables son potentes herramientas para resumir los datos de diferentes maneras. Podemos crear estas tablas utilizando las funciones group_by y summarize del paquete dplyr.

Echemos un vistazo a nuestro informe, justo después de leer los datos, creamos una tabla de resumen con el número de casos y la masa corporal media de cada especie de nuestro conjunto de datos.

Podemos utilizar group_by() para agrupar nuestros datos por especie y summarize() para calcular el número de casos y la masa_corporal_g media para cada grupo.

pinguinos %>% 
  group_by(especie) %>% 
  summarise(count = n(),
            masa_corporal_media = mean(masa_corporal_g, na.rm = TRUE))
## # A tibble: 3 × 3
##   especie count masa_corporal_media
##   <chr>   <int>               <dbl>
## 1 Adelia    152               3701.
## 2 Barbijo    68               3733.
## 3 Papúa     124               5076.

La función n() devuelve el número de casos y la función mean calcula la media o promedio. El parámetro na.rm = TRUE indica a la función que elimine los valores faltantes (NA) antes de realizar el cálculo.

Pregunta: ¿Qué pasa si no se utiliza group_by() antes de summarise()? Probémoslo y discutamos lo que ocurre.

pinguinos %>% 
  summarise(count = n(),
            masa_corporal_media = mean(masa_corporal_g, na.rm = TRUE))
## # A tibble: 1 × 2
##   count masa_corporal_media
##   <int>               <dbl>
## 1   344               4202.

Así que si no agrupamos por la especie primero, obtendremos una sola estadística de resumen (n y media en este caso) para todo el conjunto de datos.

Ahora, queremos la media de la masa corporal en kilogramos y con dos decimales. Podemos cambiar nuestra llamada a summarise() para obtener ese cálculo.

pinguinos %>% 
  group_by(especie) %>% 
  summarise(count = n(),
            masa_corporal_media = round(mean(masa_corporal_g/1000, na.rm = TRUE), 2))
## # A tibble: 3 × 3
##   especie count masa_corporal_media
##   <chr>   <int>               <dbl>
## 1 Adelia    152                3.7 
## 2 Barbijo    68                3.73
## 3 Papúa     124                5.08

Primero dividimos la masa corporal por 1000 para transformarla de gramos a kilogramos y luego utilizamos la función round() para redondear a sólo dos decimales.

Ahora estamos en el punto en el que queremos guardar esta información resumida como una variable para poder utilizarla en posteriores análisis y formatos.

Así que vamos a añadir una asignación de variable a esa primera línea:

resumen <- pinguinos %>% 
  group_by(especie) %>% 
  summarise(count = n(),
            masa_corporal_media = round(mean(masa_corporal_g/1000, na.rm = TRUE), 2))

Dándole formato a la tabla

Para que nuestra tabla se vea mejor en un informe, tenemos que cambiar algunos de sus elementos. Por ejemplo, el nombre de las variables debe ser informativo para una persona (de momento son nombres útiles para una computadora), y podemos añadirle un título y cambiar la alineación de los números.

Podemos hacerlo con la función kable.

resumen %>% 
  knitr::kable(col.names = c("Especie", "Cantidad", "Masa corporal media"),
               align = "lcc",
               caption = "Resumen de los pingüinos en el dataset por especie.")
Resumen de los pingüinos en el dataset por especie.
Especie Cantidad Masa corporal media
Adelia 152 3.70
Barbijo 68 3.73
Papúa 124 5.08

Podemos hacer mucho más con otras funciones (o “verbos”) de dplyr. Veamos algunos más.

Creando nuevas variables

Muchas veces querremos trabajar con información que se deriva de los datos originales. Esto se suele hacer añadiendo una nueva columna. Lo hacemos con la función mutate().

Podemos añadir una nueva variable (llamada prop) que represente la proporción de pingüinos en cada especie con el uso de mutate().

pinguinos %>% 
  group_by(especie) %>% 
  summarise(count = n(),
            masa_corporal_media = round(mean(masa_corporal_g/1000, na.rm = TRUE), 2)) %>%
  mutate(prop = count/nrow(pinguinos))
## # A tibble: 3 × 4
##   especie count masa_corporal_media  prop
##   <chr>   <int>               <dbl> <dbl>
## 1 Adelia    152                3.7  0.442
## 2 Barbijo    68                3.73 0.198
## 3 Papúa     124                5.08 0.360

Filtrando los datos

En nuestro informe también realizamos un gráfico por especies. Para ello necesitamos mantener sólo los datos de la especie que queremos analizar. Utilizamos la función filter() para filtrar filas de un data.frame, esta función devuelve un nuevo data.frame con sólo las filas que satisfacen algunas condiciones.

Podemos utilizar operadores lógicos (>, <, >=, <=, ==) para crear condiciones a partir de variables numéricas. Estos operadores también son útiles para fechas y cadenas de texto. El siguiente código aplica una condición (que sea igual a) para datos de tipo texto (la columna especie).

pinguinos %>% 
  filter(especie == "Papúa")
## # A tibble: 124 × 8
##    especie isla  largo_pico_mm alto_pico_mm largo_aleta_mm masa_corporal_g sexo 
##    <chr>   <chr>         <dbl>        <dbl>          <dbl>           <dbl> <chr>
##  1 Papúa   Bisc…          46.1         13.2            211            4500 hemb…
##  2 Papúa   Bisc…          50           16.3            230            5700 macho
##  3 Papúa   Bisc…          48.7         14.1            210            4450 hemb…
##  4 Papúa   Bisc…          50           15.2            218            5700 macho
##  5 Papúa   Bisc…          47.6         14.5            215            5400 macho
##  6 Papúa   Bisc…          46.5         13.5            210            4550 hemb…
##  7 Papúa   Bisc…          45.4         14.6            211            4800 hemb…
##  8 Papúa   Bisc…          46.7         15.3            219            5200 macho
##  9 Papúa   Bisc…          43.3         13.4            209            4400 hemb…
## 10 Papúa   Bisc…          46.8         15.4            215            5150 macho
## # ℹ 114 more rows
## # ℹ 1 more variable: anio <dbl>

Actividad: Escribe el código necesario para filtrar todos los pingüinos de la isla Torgersen.

Actividad: Ahora escribe el código para filtrar todos los pingüinos con longitud de aleta mayor a 200.

LS0tDQp0aXRsZTogIk1hbmlwdWxhbmRvIGRhdG9zIg0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiBmYWxzZQ0KICAgIGhpZ2hsaWdodDogdGFuZ28NCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldCgNCgllY2hvID0gVFJVRSwNCgltZXNzYWdlID0gRkFMU0UsDQoJd2FybmluZyA9IEZBTFNFDQopDQoNCmxpYnJhcnkodGlkeXZlcnNlKQ0KcGluZ3Vpbm9zIDwtIHJlYWRfY3N2KCJkYXRvcy9waW5ndWlub3MuY3N2IikNCmBgYA0KDQojIyBDcmVhbmRvIHRhYmxhcyBkZSByZXN1bWVuDQoNCkVuIHVuYSBob2phIGRlIGPDoWxjdWxvLCBsYXMgdGFibGFzIGRpbsOhbWljYXMgbyBwaXZvdCB0YWJsZXMgc29uIHBvdGVudGVzIGhlcnJhbWllbnRhcyBwYXJhIHJlc3VtaXIgbG9zIGRhdG9zIGRlIGRpZmVyZW50ZXMgbWFuZXJhcy4gUG9kZW1vcyBjcmVhciBlc3RhcyB0YWJsYXMgdXRpbGl6YW5kbyBsYXMgZnVuY2lvbmVzIGBncm91cF9ieWAgeSBgc3VtbWFyaXplYCBkZWwgcGFxdWV0ZSBkcGx5ci4gDQoNCkVjaGVtb3MgdW4gdmlzdGF6byBhIG51ZXN0cm8gaW5mb3JtZSwganVzdG8gZGVzcHXDqXMgZGUgbGVlciBsb3MgZGF0b3MsIGNyZWFtb3MgdW5hIHRhYmxhIGRlIHJlc3VtZW4gY29uIGVsIG7Dum1lcm8gZGUgY2Fzb3MgeSBsYSBtYXNhIGNvcnBvcmFsIG1lZGlhIGRlIGNhZGEgZXNwZWNpZSBkZSBudWVzdHJvIGNvbmp1bnRvIGRlIGRhdG9zLg0KDQpQb2RlbW9zIHV0aWxpemFyIGBncm91cF9ieSgpYCBwYXJhIGFncnVwYXIgbnVlc3Ryb3MgZGF0b3MgcG9yICoqZXNwZWNpZSoqIHkgYHN1bW1hcml6ZSgpYCBwYXJhIGNhbGN1bGFyIGVsIG7Dum1lcm8gZGUgY2Fzb3MgeSBsYSAqKm1hc2FfY29ycG9yYWxfZyoqIG1lZGlhIHBhcmEgY2FkYSBncnVwby4NCg0KYGBge3J9DQoNCnBpbmd1aW5vcyAlPiUgDQogIGdyb3VwX2J5KGVzcGVjaWUpICU+JSANCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLA0KICAgICAgICAgICAgbWFzYV9jb3Jwb3JhbF9tZWRpYSA9IG1lYW4obWFzYV9jb3Jwb3JhbF9nLCBuYS5ybSA9IFRSVUUpKQ0KDQpgYGANCg0KTGEgZnVuY2nDs24gYG4oKWAgZGV2dWVsdmUgZWwgbsO6bWVybyBkZSBjYXNvcyB5IGxhIGZ1bmNpw7NuIGBtZWFuYCBjYWxjdWxhIGxhIG1lZGlhIG8gcHJvbWVkaW8uIEVsIHBhcsOhbWV0cm8gYG5hLnJtID0gVFJVRWAgaW5kaWNhIGEgbGEgZnVuY2nDs24gcXVlIGVsaW1pbmUgbG9zIHZhbG9yZXMgZmFsdGFudGVzIChgTkFgKSBhbnRlcyBkZSByZWFsaXphciBlbCBjw6FsY3Vsby4NCg0KPiBQcmVndW50YTogwr9RdcOpIHBhc2Egc2kgbm8gc2UgdXRpbGl6YSBgZ3JvdXBfYnkoKWAgYW50ZXMgZGUgYHN1bW1hcmlzZSgpYD8gUHJvYsOpbW9zbG8geSBkaXNjdXRhbW9zIGxvIHF1ZSBvY3VycmUuDQoNCmBgYHtyfQ0KcGluZ3Vpbm9zICU+JSANCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLA0KICAgICAgICAgICAgbWFzYV9jb3Jwb3JhbF9tZWRpYSA9IG1lYW4obWFzYV9jb3Jwb3JhbF9nLCBuYS5ybSA9IFRSVUUpKQ0KYGBgDQoNCkFzw60gcXVlIHNpIG5vIGFncnVwYW1vcyBwb3IgbGEgZXNwZWNpZSBwcmltZXJvLCBvYnRlbmRyZW1vcyB1bmEgc29sYSBlc3RhZMOtc3RpY2EgZGUgcmVzdW1lbiAobiB5IG1lZGlhIGVuIGVzdGUgY2FzbykgcGFyYSB0b2RvIGVsIGNvbmp1bnRvIGRlIGRhdG9zLg0KDQpBaG9yYSwgcXVlcmVtb3MgbGEgbWVkaWEgZGUgbGEgbWFzYSBjb3Jwb3JhbCBlbiBraWxvZ3JhbW9zIHkgY29uIGRvcyBkZWNpbWFsZXMuIFBvZGVtb3MgY2FtYmlhciBudWVzdHJhIGxsYW1hZGEgYSBgc3VtbWFyaXNlKClgIHBhcmEgb2J0ZW5lciBlc2UgY8OhbGN1bG8uICANCg0KYGBge3J9DQpwaW5ndWlub3MgJT4lIA0KICBncm91cF9ieShlc3BlY2llKSAlPiUgDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwNCiAgICAgICAgICAgIG1hc2FfY29ycG9yYWxfbWVkaWEgPSByb3VuZChtZWFuKG1hc2FfY29ycG9yYWxfZy8xMDAwLCBuYS5ybSA9IFRSVUUpLCAyKSkNCmBgYA0KDQpQcmltZXJvIGRpdmlkaW1vcyBsYSBtYXNhIGNvcnBvcmFsIHBvciAxMDAwIHBhcmEgdHJhbnNmb3JtYXJsYSBkZSBncmFtb3MgYSBraWxvZ3JhbW9zIHkgbHVlZ28gdXRpbGl6YW1vcyBsYSBmdW5jacOzbiBgcm91bmQoKWAgcGFyYSByZWRvbmRlYXIgYSBzw7NsbyBkb3MgZGVjaW1hbGVzLg0KDQpBaG9yYSBlc3RhbW9zIGVuIGVsIHB1bnRvIGVuIGVsIHF1ZSBxdWVyZW1vcyBndWFyZGFyIGVzdGEgaW5mb3JtYWNpw7NuIHJlc3VtaWRhIGNvbW8gdW5hIHZhcmlhYmxlIHBhcmEgcG9kZXIgdXRpbGl6YXJsYSBlbiBwb3N0ZXJpb3JlcyBhbsOhbGlzaXMgeSBmb3JtYXRvcy4NCg0KQXPDrSBxdWUgdmFtb3MgYSBhw7FhZGlyIHVuYSBhc2lnbmFjacOzbiBkZSB2YXJpYWJsZSBhIGVzYSBwcmltZXJhIGzDrW5lYToNCg0KYGBge3J9DQpyZXN1bWVuIDwtIHBpbmd1aW5vcyAlPiUgDQogIGdyb3VwX2J5KGVzcGVjaWUpICU+JSANCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLA0KICAgICAgICAgICAgbWFzYV9jb3Jwb3JhbF9tZWRpYSA9IHJvdW5kKG1lYW4obWFzYV9jb3Jwb3JhbF9nLzEwMDAsIG5hLnJtID0gVFJVRSksIDIpKQ0KYGBgDQoNCiMjIETDoW5kb2xlIGZvcm1hdG8gYSBsYSB0YWJsYQ0KDQpQYXJhIHF1ZSBudWVzdHJhIHRhYmxhIHNlIHZlYSBtZWpvciBlbiB1biBpbmZvcm1lLCB0ZW5lbW9zIHF1ZSBjYW1iaWFyIGFsZ3Vub3MgZGUgc3VzIGVsZW1lbnRvcy4gUG9yIGVqZW1wbG8sIGVsIG5vbWJyZSBkZSBsYXMgdmFyaWFibGVzIGRlYmUgc2VyIGluZm9ybWF0aXZvIHBhcmEgdW5hIHBlcnNvbmEgKGRlIG1vbWVudG8gc29uIG5vbWJyZXMgw7p0aWxlcyBwYXJhIHVuYSBjb21wdXRhZG9yYSksIHkgcG9kZW1vcyBhw7FhZGlybGUgdW4gdMOtdHVsbyB5IGNhbWJpYXIgbGEgYWxpbmVhY2nDs24gZGUgbG9zIG7Dum1lcm9zLg0KDQpQb2RlbW9zIGhhY2VybG8gY29uIGxhIGZ1bmNpw7NuIGBrYWJsZWAuDQoNCmBgYHtyfQ0KcmVzdW1lbiAlPiUgDQogIGtuaXRyOjprYWJsZShjb2wubmFtZXMgPSBjKCJFc3BlY2llIiwgIkNhbnRpZGFkIiwgIk1hc2EgY29ycG9yYWwgbWVkaWEiKSwNCiAgICAgICAgICAgICAgIGFsaWduID0gImxjYyIsDQogICAgICAgICAgICAgICBjYXB0aW9uID0gIlJlc3VtZW4gZGUgbG9zIHBpbmfDvGlub3MgZW4gZWwgZGF0YXNldCBwb3IgZXNwZWNpZS4iKQ0KYGBgDQoNClBvZGVtb3MgaGFjZXIgbXVjaG8gbcOhcyBjb24gb3RyYXMgZnVuY2lvbmVzIChvICJ2ZXJib3MiKSBkZSBkcGx5ci4gVmVhbW9zIGFsZ3Vub3MgbcOhcy4NCg0KIyMgQ3JlYW5kbyBudWV2YXMgdmFyaWFibGVzDQoNCk11Y2hhcyB2ZWNlcyBxdWVycmVtb3MgdHJhYmFqYXIgY29uIGluZm9ybWFjacOzbiBxdWUgc2UgZGVyaXZhIGRlIGxvcyBkYXRvcyBvcmlnaW5hbGVzLiBFc3RvIHNlIHN1ZWxlIGhhY2VyIGHDsWFkaWVuZG8gdW5hIG51ZXZhIGNvbHVtbmEuIExvIGhhY2Vtb3MgY29uIGxhIGZ1bmNpw7NuIGBtdXRhdGUoKWAuDQoNClBvZGVtb3MgYcOxYWRpciB1bmEgbnVldmEgdmFyaWFibGUgKGxsYW1hZGEgYHByb3BgKSBxdWUgcmVwcmVzZW50ZSBsYSBwcm9wb3JjacOzbiBkZSBwaW5nw7xpbm9zIGVuIGNhZGEgKiplc3BlY2llKiogY29uIGVsIHVzbyBkZSBgbXV0YXRlKClgLiANCg0KYGBge3J9DQpwaW5ndWlub3MgJT4lIA0KICBncm91cF9ieShlc3BlY2llKSAlPiUgDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwNCiAgICAgICAgICAgIG1hc2FfY29ycG9yYWxfbWVkaWEgPSByb3VuZChtZWFuKG1hc2FfY29ycG9yYWxfZy8xMDAwLCBuYS5ybSA9IFRSVUUpLCAyKSkgJT4lDQogIG11dGF0ZShwcm9wID0gY291bnQvbnJvdyhwaW5ndWlub3MpKQ0KDQpgYGANCg0KIyMgRmlsdHJhbmRvIGxvcyBkYXRvcw0KDQpFbiBudWVzdHJvIGluZm9ybWUgdGFtYmnDqW4gcmVhbGl6YW1vcyB1biBncsOhZmljbyBwb3IgZXNwZWNpZXMuIFBhcmEgZWxsbyBuZWNlc2l0YW1vcyBtYW50ZW5lciBzw7NsbyBsb3MgZGF0b3MgZGUgbGEgZXNwZWNpZSBxdWUgcXVlcmVtb3MgYW5hbGl6YXIuICBVdGlsaXphbW9zIGxhIGZ1bmNpw7NuIGBmaWx0ZXIoKWAgcGFyYSBmaWx0cmFyIGZpbGFzIGRlIHVuIGRhdGEuZnJhbWUsIGVzdGEgZnVuY2nDs24gZGV2dWVsdmUgdW4gbnVldm8gZGF0YS5mcmFtZSBjb24gc8OzbG8gbGFzIGZpbGFzIHF1ZSBzYXRpc2ZhY2VuIGFsZ3VuYXMgY29uZGljaW9uZXMuDQoNClBvZGVtb3MgdXRpbGl6YXIgb3BlcmFkb3JlcyBsw7NnaWNvcyAoYD5gLCBgPGAsIGA+PWAsIGA8PWAsIGA9PWApIHBhcmEgY3JlYXIgY29uZGljaW9uZXMgYSBwYXJ0aXIgZGUgdmFyaWFibGVzIG51bcOpcmljYXMuIEVzdG9zIG9wZXJhZG9yZXMgdGFtYmnDqW4gc29uIMO6dGlsZXMgcGFyYSBmZWNoYXMgeSBjYWRlbmFzIGRlIHRleHRvLiBFbCBzaWd1aWVudGUgY8OzZGlnbyBhcGxpY2EgdW5hIGNvbmRpY2nDs24gKHF1ZSBzZWEgaWd1YWwgYSkgcGFyYSBkYXRvcyBkZSB0aXBvIHRleHRvIChsYSBjb2x1bW5hIGVzcGVjaWUpLg0KDQpgYGB7cn0NCnBpbmd1aW5vcyAlPiUgDQogIGZpbHRlcihlc3BlY2llID09ICJQYXDDumEiKQ0KYGBgDQoNCj4gQWN0aXZpZGFkOiBFc2NyaWJlIGVsIGPDs2RpZ28gbmVjZXNhcmlvIHBhcmEgZmlsdHJhciB0b2RvcyBsb3MgcGluZ8O8aW5vcyBkZSBsYSBpc2xhIFRvcmdlcnNlbi4NCg0KPiBBY3RpdmlkYWQ6IEFob3JhIGVzY3JpYmUgZWwgY8OzZGlnbyBwYXJhIGZpbHRyYXIgdG9kb3MgbG9zIHBpbmfDvGlub3MgY29uIGxvbmdpdHVkIGRlIGFsZXRhIG1heW9yIGEgMjAwLg0KDQo=