Capítulo 13 Incursión a tidyverse
- Intentaremos que nuestros datos sean Tidy data
- Conocemos un formato amable de almacenar los datos como son los
data.frame
de tipotibble
Sin embargo muchas veces los datos no los tenemos en el formato deseado, o directamente queremos realizar algunas transformaciones en los mismos, crear nuevas variables u obtener resúmenes numéricos. En esta sección aprenderemos a explorar, procesar, depurar, transformar y analizar numéricamente los datos, haciendo uso principalmente de los paquetes tidyverse y skimr
El entorno tidyverse es una de las herramientas más importantes en el manejo de datos en R
, una colección de paquetes pensada para el manejo, la exploración, el análisis y la visualización de datos, compartiendo una misma filosofía y gramática. Puedes ver su documentación en https://www.tidyverse.org/. Esta sección pretende ser una introducción a dicho entorno, y lo haremos principalmente con el conjunto de datos starwars
, del paquete dplyr (ya cargado en tidyverse).
starwars
## # A tibble: 87 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke S… 172 77 blond fair blue 19 male mascu…
## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 4 Darth … 202 136 none white yellow 41.9 male mascu…
## 5 Leia O… 150 49 brown light brown 19 fema… femin…
## 6 Owen L… 178 120 brown, grey light blue 52 male mascu…
## 7 Beru W… 165 75 brown light blue 47 fema… femin…
## 8 R5-D4 97 32 <NA> white, red red NA none mascu…
## 9 Biggs … 183 84 black light brown 24 male mascu…
## 10 Obi-Wa… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## # … with 77 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
Dicho conjunto de datos, extraída de la Star Wars API, recopila diferentes datos y características de los personajes de la saga Star Wars. Como habrás advertido, starwars
es una tabla en un formato ya conocido, un tibble
, en el que se nos especifica al inicio de la tabla de qué tipo son cada columna:
-
int
: números enteros. -
dbl
: números reales (o racionales). -
chr
: cadenas de texto. -
lgl
: valores lógicos (TRUE
oFALSE
). -
fct
: factores, variables cualitativas (categorías). -
date
: fechas.
Las funciones que veremos a lo largo de esta sección siempre van a compartir una misma metodología: primero escribimos el nombre una tabla (data.frame
o tibble
), después lo que queremos hacer a dicho conjunto de datos (con las variables SIN comillas) encandenando órdenes con %>%
(lo que se conoce como pipes), y obtenemos una nueva tabla en el mismo formato de entrada.
# Tipo de datos
class(starwars)
## [1] "tbl_df" "tbl" "data.frame"
# Dimensión de los datos
dim(starwars)
## [1] 87 14
Con glimpse(starwars)
podemos obtener una visión global de las variables que tenemos.
# Resumen por columnas
glimpse(starwars)
## Rows: 87
## Columns: 14
## $ name <chr> "Luke Skywalker", "C-3PO", "R2-D2", "Darth Vader", "Leia Or…
## $ height <int> 172, 167, 96, 202, 150, 178, 165, 97, 183, 182, 188, 180, 2…
## $ mass <dbl> 77.0, 75.0, 32.0, 136.0, 49.0, 120.0, 75.0, 32.0, 84.0, 77.…
## $ hair_color <chr> "blond", NA, NA, "none", "brown", "brown, grey", "brown", N…
## $ skin_color <chr> "fair", "gold", "white, blue", "white", "light", "light", "…
## $ eye_color <chr> "blue", "yellow", "red", "yellow", "brown", "blue", "blue",…
## $ birth_year <dbl> 19.0, 112.0, 33.0, 41.9, 19.0, 52.0, 47.0, NA, 24.0, 57.0, …
## $ sex <chr> "male", "none", "none", "male", "female", "male", "female",…
## $ gender <chr> "masculine", "masculine", "masculine", "masculine", "femini…
## $ homeworld <chr> "Tatooine", "Tatooine", "Naboo", "Tatooine", "Alderaan", "T…
## $ species <chr> "Human", "Droid", "Droid", "Human", "Human", "Human", "Huma…
## $ films <list> <"The Empire Strikes Back", "Revenge of the Sith", "Return…
## $ vehicles <list> <"Snowspeeder", "Imperial Speeder Bike">, <>, <>, <>, "Imp…
## $ starships <list> <"X-wing", "Imperial shuttle">, <>, <>, "TIE Advanced x1",…
Los datos podemos verlos escribiendo el nombre de la tabla en la consola (recuerda que si es un tibble
, para evitar saturar la consola, te saca un extracto, no todas las columnas y filas) o bien con la función print()
, indicándole número de filas (n = 15
por ejemplo) y número de columnas (width = Inf
si queremos mostrar todas).
# Imprimir personalizado
print(starwars, n = 5, width = Inf)
## # A tibble: 87 × 14
## name height mass hair_color skin_color eye_color birth_year sex
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr>
## 1 Luke Skywalker 172 77 blond fair blue 19 male
## 2 C-3PO 167 75 <NA> gold yellow 112 none
## 3 R2-D2 96 32 <NA> white, blue red 33 none
## 4 Darth Vader 202 136 none white yellow 41.9 male
## 5 Leia Organa 150 49 brown light brown 19 female
## gender homeworld species films vehicles starships
## <chr> <chr> <chr> <list> <list> <list>
## 1 masculine Tatooine Human <chr [5]> <chr [2]> <chr [2]>
## 2 masculine Tatooine Droid <chr [6]> <chr [0]> <chr [0]>
## 3 masculine Naboo Droid <chr [7]> <chr [0]> <chr [0]>
## 4 masculine Tatooine Human <chr [4]> <chr [0]> <chr [1]>
## 5 feminine Alderaan Human <chr [5]> <chr [1]> <chr [0]>
## # … with 82 more rows
Fíjate que las 3 últimas variables son de tipo lista (echa un vistazo a Listas). Por ejemplo, en starwars$films
se guardan para cada personaje la colección de películas de la saga en las que aparece (algunos tendrán 1 solo nombre, otros 7).

Imagen/gráfica 13.1: Cheet sheet de las opciones del paquete dplyr para la manipulación de datos extraída de https://github.com/rstudio/cheatsheets/blob/master/data-transformation.pdf
13.1 Operaciones con filas
Empecemos por cómo seleccionar filas. Principalmente tenemos tres opciones: seleccionarlas en base a algún filtro o condición (solo los mayores de tal edad, por ejemplo), extraer filas por su índice de fila o extraer filas aleatoriamente.
13.1.1 Seleccionar filas (filter, slice)
La función filter()
nos permite seleccionar filas en base a que se cumpla una o varias condiciones respecto a las variables. Para usarla basta con que introduzcamos como argumento el conjunto de condiciones que debe cumplir (recuerda: nombre de columnas sin comillas). Supongamos que queremos por ejemplo seleccionar solo los personajes con ojos marrones: nos bastará con usar filter()
con la condición eye_color == "brown"
.
starwars %>% filter(eye_color == "brown") # con ojos marrones
## # A tibble: 21 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Leia Or… 150 49 brown light brown 19 fema… femin…
## 2 Biggs D… 183 84 black light brown 24 male mascu…
## 3 Han Solo 180 80 brown fair brown 29 male mascu…
## 4 Yoda 66 17 white green brown 896 male mascu…
## 5 Boba Fe… 183 78.2 black fair brown 31.5 male mascu…
## 6 Lando C… 177 79 black dark brown 31 male mascu…
## 7 Arvel C… NA NA brown fair brown NA male mascu…
## 8 Wicket … 88 20 brown brown brown 8 male mascu…
## 9 Quarsh … 183 NA black dark brown 62 <NA> <NA>
## 10 Shmi Sk… 163 NA black fair brown 72 fema… femin…
## # … with 11 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
En tan solo una línea hemos hecho más de lo que parece: R
ha «recorrido» (algo similar a un bucle) cada una de las filas y ha ido comprobando que fila cumple la condición y cual no. Con la misma lógica podemos seleccionar los personajes que NO TIENEN ojos marrones, cambiando ==
por !=
starwars %>% filter(eye_color != "brown") # NO tengan ojos marrones
## # A tibble: 66 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke S… 172 77 blond fair blue 19 male mascu…
## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 4 Darth … 202 136 none white yellow 41.9 male mascu…
## 5 Owen L… 178 120 brown, grey light blue 52 male mascu…
## 6 Beru W… 165 75 brown light blue 47 fema… femin…
## 7 R5-D4 97 32 <NA> white, red red NA none mascu…
## 8 Obi-Wa… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## 9 Anakin… 188 84 blond fair blue 41.9 male mascu…
## 10 Wilhuf… 180 NA auburn, gr… fair blue 64 male mascu…
## # … with 56 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
También se pueden seleccionar los personajes que tienen los ojos de una serie de colores permitidos.
## # A tibble: 45 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke S… 172 77 blond fair blue 19 male mascu…
## 2 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 3 Leia O… 150 49 brown light brown 19 fema… femin…
## 4 Owen L… 178 120 brown, grey light blue 52 male mascu…
## 5 Beru W… 165 75 brown light blue 47 fema… femin…
## 6 R5-D4 97 32 <NA> white, red red NA none mascu…
## 7 Biggs … 183 84 black light brown 24 male mascu…
## 8 Anakin… 188 84 blond fair blue 41.9 male mascu…
## 9 Wilhuf… 180 NA auburn, gr… fair blue 64 male mascu…
## 10 Chewba… 228 112 brown unknown blue 200 male mascu…
## # … with 35 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
Si es una variable numérica también podemos seleccionar por rango con between()
, por ejemplo, los personajes cuya altura está entre 120 y 160 cm.
# Con between filtramos por rango
starwars %>% filter(between(height, 120, 160))
## # A tibble: 6 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Leia Or… 150 49 brown light brown 19 fema… femini…
## 2 Mon Mot… 150 NA auburn fair blue 48 fema… femini…
## 3 Nien Nu… 160 68 none grey black NA male mascul…
## 4 Watto 137 NA black blue, grey yellow NA male mascul…
## 5 Gasgano 122 NA none white, bl… black NA male mascul…
## 6 Cordé 157 NA brown light brown NA fema… femini…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
Las condiciones se pueden concatenar y complejizar todo lo que queramos, pudiendo en pocas líneas realizar un filtro complejo, por ejemplo personajes con ohos marrones y que sean humanos.
starwars %>% # humanos con ojos marrones
filter(eye_color == "brown", species == "Human")
## # A tibble: 17 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Leia Or… 150 49 brown light brown 19 fema… femin…
## 2 Biggs D… 183 84 black light brown 24 male mascu…
## 3 Han Solo 180 80 brown fair brown 29 male mascu…
## 4 Boba Fe… 183 78.2 black fair brown 31.5 male mascu…
## 5 Lando C… 177 79 black dark brown 31 male mascu…
## 6 Arvel C… NA NA brown fair brown NA male mascu…
## 7 Shmi Sk… 163 NA black fair brown 72 fema… femin…
## 8 Mace Wi… 188 84 none dark brown 72 male mascu…
## 9 Gregar … 185 85 black dark brown NA male mascu…
## 10 Cordé 157 NA brown light brown NA fema… femin…
## 11 Dormé 165 NA brown light brown NA fema… femin…
## 12 Dooku 193 80 white fair brown 102 male mascu…
## 13 Bail Pr… 191 NA black tan brown 67 male mascu…
## 14 Jango F… 183 79 black tan brown 66 male mascu…
## 15 Raymus … 188 79 brown light brown NA male mascu…
## 16 Poe Dam… NA NA brown light brown NA male mascu…
## 17 Padmé A… 165 45 brown light brown 46 fema… femin…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
También podemos filtrar personajes con ojos marrones, azules o rojos, que no sean humanos, y con menos de 50 años.
# humanos con ojos marrones, azules o rojos, que no sean humanos, y menos de 50a
starwars %>%
filter(eye_color %in% c("brown", "blue", "red"),
species != "Human", birth_year < 50)
## # A tibble: 4 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 2 IG-88 200 140 none metal red 15 none mascu…
## 3 Wicket S… 88 20 brown brown brown 8 male mascu…
## 4 Barriss … 166 50 black yellow blue 40 fema… femin…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
Muchas veces querremos extraer filas simplemente por el lugar que ocupan, sin hacer que dependa de ninguna condición. Vamos a extraer las filas quinta, sexta, séptima, octava, novena y décima con slice()
.
# slice: extramos filas por índice de fila.
starwars %>% slice(5:10) # filas de la 5 a la 10
## # A tibble: 6 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Leia Or… 150 49 brown light brown 19 fema… femin…
## 2 Owen La… 178 120 brown, grey light blue 52 male mascu…
## 3 Beru Wh… 165 75 brown light blue 47 fema… femin…
## 4 R5-D4 97 32 <NA> white, red red NA none mascu…
## 5 Biggs D… 183 84 black light brown 24 male mascu…
## 6 Obi-Wan… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
Podemos combinar los índices para extraer por ejemplo solo los pares o filas concretas separadas por los espacios que queramos.
## # A tibble: 43 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 2 Darth … 202 136 none white yellow 41.9 male mascu…
## 3 Owen L… 178 120 brown, grey light blue 52 male mascu…
## 4 R5-D4 97 32 <NA> white, red red NA none mascu…
## 5 Obi-Wa… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## 6 Wilhuf… 180 NA auburn, gr… fair blue 64 male mascu…
## 7 Han So… 180 80 brown fair brown 29 male mascu…
## 8 Jabba … 175 1358 <NA> green-tan… orange 600 herm… mascu…
## 9 Jek To… 180 110 brown fair blue NA male mascu…
## 10 Palpat… 170 75 grey pale yellow 82 male mascu…
## # … with 33 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
starwars %>% slice(c(3, 4, 10, 20, 33)) # filas 3, 4, 10, 20 y 33
## # A tibble: 5 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 2 Darth V… 202 136 none white yellow 41.9 male mascu…
## 3 Obi-Wan… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## 4 Palpati… 170 75 grey pale yellow 82 male mascu…
## 5 Finis V… 170 NA blond fair blue 91 male mascu…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
También hay opciones por defecto para directamente extraer las primeras o últimas filas con slice_head()
y slice_tail()
.
# Podemos extraer directamente las primeras o últimas filas
starwars %>% slice_head(n = 7) # 7 primeras filas
## # A tibble: 7 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke Sk… 172 77 blond fair blue 19 male mascu…
## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 4 Darth V… 202 136 none white yellow 41.9 male mascu…
## 5 Leia Or… 150 49 brown light brown 19 fema… femin…
## 6 Owen La… 178 120 brown, grey light blue 52 male mascu…
## 7 Beru Wh… 165 75 brown light blue 47 fema… femin…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
starwars %>% slice_tail(n = 3) # 3 últimas filas
## # A tibble: 3 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 BB8 NA NA none none black NA none mascu…
## 2 Captain… NA NA unknown unknown unknown NA <NA> <NA>
## 3 Padmé A… 165 45 brown light brown 46 female femin…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
Una opción también habitual es querer extraer un número de filas pero AL AZAR, pudiendo hacerlo sin reemplazamiento (una vez extraída, no se puede volver a extraer) o con reemplazamiento (con replace = TRUE
).
# También podemos hacer una extracción al azar de filas
starwars %>% slice_sample(n = 5) # 5 al azar
## # A tibble: 5 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 San Hill 191 NA none grey gold NA male mascul…
## 2 Wedge A… 170 77 brown fair hazel 21 male mascul…
## 3 Yarael … 264 NA none white yellow NA male mascul…
## 4 Mace Wi… 188 84 none dark brown 72 male mascul…
## 5 Luke Sk… 172 77 blond fair blue 19 male mascul…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
starwars %>% slice_sample(n = 100, replace = TRUE) # 100 con reemplazamiento
## # A tibble: 100 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Darth … 202 136 none white yellow 41.9 male mascu…
## 2 Shmi S… 163 NA black fair brown 72 fema… femin…
## 3 R4-P17 96 NA none silver, red red, blue NA none femin…
## 4 IG-88 200 140 none metal red 15 none mascu…
## 5 Lama Su 229 88 none grey black NA male mascu…
## 6 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 7 Lobot 175 79 none light blue 37 male mascu…
## 8 Nien N… 160 68 none grey black NA male mascu…
## 9 Ackbar 180 83 none brown mott… orange 41 male mascu…
## 10 Palpat… 170 75 grey pale yellow 82 male mascu…
## # … with 90 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
Por último, tenemos slice_min()
y slice_max()
que nos permite extraer filas en función del mínimo y máximo de una variable. Por defecto, si hay empate, mostrará todas las filas (aunque supere el número n
indicado), salvo que with_ties = FALSE
, que decidirá en caso de empate cual mostrarte
# Podemos extraer filas en función del mín/máx de una variable
starwars %>% slice_min(height, n = 5) # los 5 más bajitos
## # A tibble: 6 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Yoda 66 17 white green brown 896 male mascu…
## 2 Ratts Ty… 79 15 none grey, blue unknown NA male mascu…
## 3 Wicket S… 88 20 brown brown brown 8 male mascu…
## 4 Dud Bolt 94 45 none blue, grey yellow NA male mascu…
## 5 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 6 R4-P17 96 NA none silver, r… red, blue NA none femin…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
starwars %>% # los 5 más bajitos (sin empates, exactamente 5)
slice_min(height, n = 5, with_ties = FALSE)
## # A tibble: 5 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Yoda 66 17 white green brown 896 male mascu…
## 2 Ratts Ty… 79 15 none grey, blue unknown NA male mascu…
## 3 Wicket S… 88 20 brown brown brown 8 male mascu…
## 4 Dud Bolt 94 45 none blue, grey yellow NA male mascu…
## 5 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
starwars %>% slice_max(mass, n = 7) # los 7 más pesados
## # A tibble: 7 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Jabba … 175 1358 <NA> green-tan,… orange 600 herm… mascu…
## 2 Grievo… 216 159 none brown, whi… green, y… NA male mascu…
## 3 IG-88 200 140 none metal red 15 none mascu…
## 4 Darth … 202 136 none white yellow 41.9 male mascu…
## 5 Tarfful 234 136 brown brown blue NA male mascu…
## 6 Owen L… 178 120 brown, grey light blue 52 male mascu…
## 7 Bossk 190 113 none green red 53 male mascu…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
13.1.2 Reordenar filas (arrange)
Muchas veces necesitamos las filas ordenadas en función del valor de alguna de las variables. Para ello tenemos la función arrange()
sin más que pasarle como argumento el nombre de la variable que usaremos para la ordenación. Vamos a ordenar nuestra tabla de personajes por altura, de bajitos a altos.
# Con arrange ordenamos en base al orden de la variable que introduzcamos
starwars %>% arrange(height) # de bajitos a altos, yoda al poder
## # A tibble: 87 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Yoda 66 17 white green brown 896 male mascu…
## 2 Ratts T… 79 15 none grey, blue unknown NA male mascu…
## 3 Wicket … 88 20 brown brown brown 8 male mascu…
## 4 Dud Bolt 94 45 none blue, grey yellow NA male mascu…
## 5 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 6 R4-P17 96 NA none silver, r… red, blue NA none femin…
## 7 R5-D4 97 32 <NA> white, red red NA none mascu…
## 8 Sebulba 112 40 none grey, red orange NA male mascu…
## 9 Gasgano 122 NA none white, bl… black NA male mascu…
## 10 Watto 137 NA black blue, grey yellow NA male mascu…
## # … with 77 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
Por defecto la ordenación es de menor a mayor pero podemos invertirlo usando desc()
.
# Por defecto lo hace ascendente pero podemos cambiarlo
starwars %>% arrange(desc(height))
## # A tibble: 87 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Yarael… 264 NA none white yellow NA male mascu…
## 2 Tarfful 234 136 brown brown blue NA male mascu…
## 3 Lama Su 229 88 none grey black NA male mascu…
## 4 Chewba… 228 112 brown unknown blue 200 male mascu…
## 5 Roos T… 224 82 none grey orange NA male mascu…
## 6 Grievo… 216 159 none brown, whi… green, y… NA male mascu…
## 7 Taun We 213 NA none grey black NA fema… femin…
## 8 Rugor … 206 NA none green orange NA male mascu…
## 9 Tion M… 206 80 none grey black NA male mascu…
## 10 Darth … 202 136 none white yellow 41.9 male mascu…
## # … with 77 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
La ordenación puede realizarse en base al valor de dos o más variables: ordenará las filas en base a la primera, en caso de empate usará la segunda, en caso de empate la tercera, y así sucesivamente. Vamos a ordenar los personajes por altura y, luego, por peso.
# Podemos combinar varios criterios: ordenados de bajitos a altos,
# y en caso de empate, de pesados a ligeros. Un dato NA va siempre al final
starwars %>% arrange(height, desc(mass))
## # A tibble: 87 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Yoda 66 17 white green brown 896 male mascu…
## 2 Ratts T… 79 15 none grey, blue unknown NA male mascu…
## 3 Wicket … 88 20 brown brown brown 8 male mascu…
## 4 Dud Bolt 94 45 none blue, grey yellow NA male mascu…
## 5 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 6 R4-P17 96 NA none silver, r… red, blue NA none femin…
## 7 R5-D4 97 32 <NA> white, red red NA none mascu…
## 8 Sebulba 112 40 none grey, red orange NA male mascu…
## 9 Gasgano 122 NA none white, bl… black NA male mascu…
## 10 Watto 137 NA black blue, grey yellow NA male mascu…
## # … with 77 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
WARNING: valores ausentes
Si te fijas los valores ausentes van siempre al final de la ordenación. Luego veremos como eliminarlos si quisiéramos.
Como estarás imaginando podemos combinar varias acciones en pocas líneas, filtrando datos a la vez que ordenamos el filtro resultante. Como ejemplo vamos a seleccionar los personajes humanos, hombres, de ojos marrones, y en orden altura descendente y peso ascendente.
# Podemos combinar varias acciones en pocas líneas
starwars %>%
filter(eye_color == "brown",
species == "Human", sex == "male") %>%
arrange(height, desc(mass))
## # A tibble: 12 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Lando C… 177 79 black dark brown 31 male mascu…
## 2 Han Solo 180 80 brown fair brown 29 male mascu…
## 3 Biggs D… 183 84 black light brown 24 male mascu…
## 4 Jango F… 183 79 black tan brown 66 male mascu…
## 5 Boba Fe… 183 78.2 black fair brown 31.5 male mascu…
## 6 Gregar … 185 85 black dark brown NA male mascu…
## 7 Mace Wi… 188 84 none dark brown 72 male mascu…
## 8 Raymus … 188 79 brown light brown NA male mascu…
## 9 Bail Pr… 191 NA black tan brown 67 male mascu…
## 10 Dooku 193 80 white fair brown 102 male mascu…
## 11 Arvel C… NA NA brown fair brown NA male mascu…
## 12 Poe Dam… NA NA brown light brown NA male mascu…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
13.1.3 Eliminar filas y duplicados
La misma lógica que hemos usado para seleccionar filas podemos usarla para eliminar filas, simplemente negando la condición de filtrado. Por ejemplo, vamos a eliminar las 5 primeras filas.
# Eliminamos por índices
starwars %>% slice(-(1:5)) # eliminamos las 5 primeras filas
## # A tibble: 82 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Owen L… 178 120 brown, grey light blue 52 male mascu…
## 2 Beru W… 165 75 brown light blue 47 fema… femin…
## 3 R5-D4 97 32 <NA> white, red red NA none mascu…
## 4 Biggs … 183 84 black light brown 24 male mascu…
## 5 Obi-Wa… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## 6 Anakin… 188 84 blond fair blue 41.9 male mascu…
## 7 Wilhuf… 180 NA auburn, gr… fair blue 64 male mascu…
## 8 Chewba… 228 112 brown unknown blue 200 male mascu…
## 9 Han So… 180 80 brown fair brown 29 male mascu…
## 10 Greedo 173 74 <NA> green black 44 male mascu…
## # … with 72 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
Otra opción a la hora de eliminar filas es eliminar filas duplicadas (o filas con valores duplicados en alguna columna). Para ello deberemos aplicar la función distinct()
, pasándole como argumentos el nombre de las variables que usaremos para quitar duplicados, por ejemplo, aquellos personajes con igual par de color de pelo y ojos.
# Eliminamos duplicados
starwars %>% # Eliminamos registros con igual par (color_pelo, color_ojos)
distinct(hair_color, eye_color)
## # A tibble: 35 × 2
## hair_color eye_color
## <chr> <chr>
## 1 blond blue
## 2 <NA> yellow
## 3 <NA> red
## 4 none yellow
## 5 brown brown
## 6 brown, grey blue
## 7 brown blue
## 8 black brown
## 9 auburn, white blue-gray
## 10 auburn, grey blue
## # … with 25 more rows
Si te fijas además nos ha extraído solo las dos columnas en base a las cuales hemos eliminado duplicados. Si queremos que nos mantenga toda la tabla deberemos explicitarlo con .keep_all = TRUE
.
# Eliminamos duplicados
starwars %>% # Eliminamos registros con igual par (color_pelo, color_ojos)
distinct(hair_color, eye_color,
.keep_all = TRUE) # .keep_all = TRUE mantiene todas columnas
## # A tibble: 35 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke S… 172 77 blond fair blue 19 male mascu…
## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 4 Darth … 202 136 none white yellow 41.9 male mascu…
## 5 Leia O… 150 49 brown light brown 19 fema… femin…
## 6 Owen L… 178 120 brown, grey light blue 52 male mascu…
## 7 Beru W… 165 75 brown light blue 47 fema… femin…
## 8 Biggs … 183 84 black light brown 24 male mascu…
## 9 Obi-Wa… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## 10 Wilhuf… 180 NA auburn, gr… fair blue 64 male mascu…
## # … with 25 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
Si no incluimos ningún nombre de columna nos eliminará solo los registros que tengan TODOS los campos duplicados.
# Duplicamos el conjunto para probarlo
duplicado_starwars <- rbind(starwars, starwars)
dim(duplicado_starwars)
## [1] 174 14
# Eliminamos duplicados (filas exactamente iguales)
duplicado_starwars %>% distinct()
## # A tibble: 87 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke S… 172 77 blond fair blue 19 male mascu…
## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 4 Darth … 202 136 none white yellow 41.9 male mascu…
## 5 Leia O… 150 49 brown light brown 19 fema… femin…
## 6 Owen L… 178 120 brown, grey light blue 52 male mascu…
## 7 Beru W… 165 75 brown light blue 47 fema… femin…
## 8 R5-D4 97 32 <NA> white, red red NA none mascu…
## 9 Biggs … 183 84 black light brown 24 male mascu…
## 10 Obi-Wa… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## # … with 77 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
dim(duplicado_starwars %>% distinct())
## [1] 87 14
13.2 Operaciones con columnas
Ya hemos visto algunas opciones para manejar filas. Pasemos a seleccionar columnas o construir columnas/variables nuevas en base a las ya existentes.
13.2.1 Seleccionar (select) y extraer (pull) columnas
La opción más sencilla es usar la función select()
pasándole como argumentos los nombres de columnas (¡SIN COMILLAS!) queremos seleccionar, por ejemplo, color de pelo, piel y ojos.
# select: columnas a seleccionar sin comillas
starwars %>% # seleccionamos solo 3 columnas: pelo, piel y ojos
select(hair_color, skin_color, eye_color)
## # A tibble: 87 × 3
## hair_color skin_color eye_color
## <chr> <chr> <chr>
## 1 blond fair blue
## 2 <NA> gold yellow
## 3 <NA> white, blue red
## 4 none white yellow
## 5 brown light brown
## 6 brown, grey light blue
## 7 brown light blue
## 8 <NA> white, red red
## 9 black light brown
## 10 auburn, white fair blue-gray
## # … with 77 more rows
Si las columnas a seleccionar sabemos que son consecutivas, podemos indicarle que las seleccionemos desde una columna inicial hasta una columna inicial pasando por todas.
# Podemos seleccionar columnas en orden: desde nombre hasta año nacim.
starwars %>% select(name:birth_year)
## # A tibble: 87 × 7
## name height mass hair_color skin_color eye_color birth_year
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl>
## 1 Luke Skywalker 172 77 blond fair blue 19
## 2 C-3PO 167 75 <NA> gold yellow 112
## 3 R2-D2 96 32 <NA> white, bl… red 33
## 4 Darth Vader 202 136 none white yellow 41.9
## 5 Leia Organa 150 49 brown light brown 19
## 6 Owen Lars 178 120 brown, grey light blue 52
## 7 Beru Whitesun lars 165 75 brown light blue 47
## 8 R5-D4 97 32 <NA> white, red red NA
## 9 Biggs Darklighter 183 84 black light brown 24
## 10 Obi-Wan Kenobi 182 77 auburn, white fair blue-gray 57
## # … with 77 more rows
Una de las mejores opciones en este entorno es que las columnas las podemos seleccionar a través de expresiones regulares, por ejemplo, seleccionando solo aquellas columnas que compartan un sufijo común en el nombre, con ends_with()
dentro de órdenes como select()
# Podemos seleccionar columnas por sufijo y prefijo
starwars %>% select(ends_with("color")) # acaban en "color"
## # A tibble: 87 × 3
## hair_color skin_color eye_color
## <chr> <chr> <chr>
## 1 blond fair blue
## 2 <NA> gold yellow
## 3 <NA> white, blue red
## 4 none white yellow
## 5 brown light brown
## 6 brown, grey light blue
## 7 brown light blue
## 8 <NA> white, red red
## 9 black light brown
## 10 auburn, white fair blue-gray
## # … with 77 more rows
De una manera similar podemos seleccionar columnas cuyo nombre empiecen o contengan alguna cadena de texto concreta
starwars %>% select(starts_with("h")) # empiezan por h
## # A tibble: 87 × 3
## height hair_color homeworld
## <int> <chr> <chr>
## 1 172 blond Tatooine
## 2 167 <NA> Tatooine
## 3 96 <NA> Naboo
## 4 202 none Tatooine
## 5 150 brown Alderaan
## 6 178 brown, grey Tatooine
## 7 165 brown Tatooine
## 8 97 <NA> Tatooine
## 9 183 black Tatooine
## 10 182 auburn, white Stewjon
## # … with 77 more rows
starwars %>% select(contains("h")) # contienen la h
## # A tibble: 87 × 6
## height hair_color birth_year homeworld vehicles starships
## <int> <chr> <dbl> <chr> <list> <list>
## 1 172 blond 19 Tatooine <chr [2]> <chr [2]>
## 2 167 <NA> 112 Tatooine <chr [0]> <chr [0]>
## 3 96 <NA> 33 Naboo <chr [0]> <chr [0]>
## 4 202 none 41.9 Tatooine <chr [0]> <chr [1]>
## 5 150 brown 19 Alderaan <chr [1]> <chr [0]>
## 6 178 brown, grey 52 Tatooine <chr [0]> <chr [0]>
## 7 165 brown 47 Tatooine <chr [0]> <chr [0]>
## 8 97 <NA> NA Tatooine <chr [0]> <chr [0]>
## 9 183 black 24 Tatooine <chr [0]> <chr [1]>
## 10 182 auburn, white 57 Stewjon <chr [1]> <chr [5]>
## # … with 77 more rows
Todo lo que hemos usado para seleccionar lo podemos usar para eliminar columnas
starwars %>% # seleccionamos todas menos 3 columnas: pelo, piel y ojos
select(-c(hair_color, skin_color, eye_color))
## # A tibble: 87 × 11
## name height mass birth_year sex gender homeworld species films vehicles
## <chr> <int> <dbl> <dbl> <chr> <chr> <chr> <chr> <lis> <list>
## 1 Luke S… 172 77 19 male mascu… Tatooine Human <chr… <chr [2…
## 2 C-3PO 167 75 112 none mascu… Tatooine Droid <chr… <chr [0…
## 3 R2-D2 96 32 33 none mascu… Naboo Droid <chr… <chr [0…
## 4 Darth … 202 136 41.9 male mascu… Tatooine Human <chr… <chr [0…
## 5 Leia O… 150 49 19 fema… femin… Alderaan Human <chr… <chr [1…
## 6 Owen L… 178 120 52 male mascu… Tatooine Human <chr… <chr [0…
## 7 Beru W… 165 75 47 fema… femin… Tatooine Human <chr… <chr [0…
## 8 R5-D4 97 32 NA none mascu… Tatooine Droid <chr… <chr [0…
## 9 Biggs … 183 84 24 male mascu… Tatooine Human <chr… <chr [0…
## 10 Obi-Wa… 182 77 57 male mascu… Stewjon Human <chr… <chr [1…
## # … with 77 more rows, and 1 more variable: starships <list>
Incluso nos permite seleccionar aquellas columnas que son del mismo tipo (imagina que necesitamos solo las columnas numéricas para calcular ciertas estadísticas) con where()
.
# Seleccionamos solo la columnas numéricas
starwars %>% select(where(is.numeric))
## # A tibble: 87 × 3
## height mass birth_year
## <int> <dbl> <dbl>
## 1 172 77 19
## 2 167 75 112
## 3 96 32 33
## 4 202 136 41.9
## 5 150 49 19
## 6 178 120 52
## 7 165 75 47
## 8 97 32 NA
## 9 183 84 24
## 10 182 77 57
## # … with 77 more rows
Por último, podemos no tanto seleccionar sino extraer columnas: las saca fuera de la tabla y las convierte en un vector fuera del tibble
, con la función pull()
.
starwars %>% pull(name)
## [1] "Luke Skywalker" "C-3PO" "R2-D2"
## [4] "Darth Vader" "Leia Organa" "Owen Lars"
## [7] "Beru Whitesun lars" "R5-D4" "Biggs Darklighter"
## [10] "Obi-Wan Kenobi" "Anakin Skywalker" "Wilhuff Tarkin"
## [13] "Chewbacca" "Han Solo" "Greedo"
## [16] "Jabba Desilijic Tiure" "Wedge Antilles" "Jek Tono Porkins"
## [19] "Yoda" "Palpatine" "Boba Fett"
## [22] "IG-88" "Bossk" "Lando Calrissian"
## [25] "Lobot" "Ackbar" "Mon Mothma"
## [28] "Arvel Crynyd" "Wicket Systri Warrick" "Nien Nunb"
## [31] "Qui-Gon Jinn" "Nute Gunray" "Finis Valorum"
## [34] "Jar Jar Binks" "Roos Tarpals" "Rugor Nass"
## [37] "Ric Olié" "Watto" "Sebulba"
## [40] "Quarsh Panaka" "Shmi Skywalker" "Darth Maul"
## [43] "Bib Fortuna" "Ayla Secura" "Dud Bolt"
## [46] "Gasgano" "Ben Quadinaros" "Mace Windu"
## [49] "Ki-Adi-Mundi" "Kit Fisto" "Eeth Koth"
## [52] "Adi Gallia" "Saesee Tiin" "Yarael Poof"
## [55] "Plo Koon" "Mas Amedda" "Gregar Typho"
## [58] "Cordé" "Cliegg Lars" "Poggle the Lesser"
## [61] "Luminara Unduli" "Barriss Offee" "Dormé"
## [64] "Dooku" "Bail Prestor Organa" "Jango Fett"
## [67] "Zam Wesell" "Dexter Jettster" "Lama Su"
## [70] "Taun We" "Jocasta Nu" "Ratts Tyerell"
## [73] "R4-P17" "Wat Tambor" "San Hill"
## [76] "Shaak Ti" "Grievous" "Tarfful"
## [79] "Raymus Antilles" "Sly Moore" "Tion Medon"
## [82] "Finn" "Rey" "Poe Dameron"
## [85] "BB8" "Captain Phasma" "Padmé Amidala"
13.2.2 Renombrar (rename) y reordenar (relocate) columnas
A veces también podemos querer modificar la «metainformación» de la tabla, no modificando los datos sino renombrando el orden de las columnas. Para ello debremos usar la función rename()
poniendo primero el nombre nuevo y luego el antiguo
# rename: renombrar columnas, primero el nuevo y luego el antiguo
starwars %>% rename(nombre = name, altura = height, peso = mass)
## # A tibble: 87 × 14
## nombre altura peso hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke Sk… 172 77 blond fair blue 19 male mascu…
## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 4 Darth V… 202 136 none white yellow 41.9 male mascu…
## 5 Leia Or… 150 49 brown light brown 19 fema… femin…
## 6 Owen La… 178 120 brown, gr… light blue 52 male mascu…
## 7 Beru Wh… 165 75 brown light blue 47 fema… femin…
## 8 R5-D4 97 32 <NA> white, red red NA none mascu…
## 9 Biggs D… 183 84 black light brown 24 male mascu…
## 10 Obi-Wan… 182 77 auburn, w… fair blue-gray 57 male mascu…
## # … with 77 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
De la misma manera podemos reordenar las columnas, indicando el nombre de columnas que queremos mover, y con .after
y/o .before
para indicar antes o después de que columnas queremos moverlas.
starwars %>% # altura y masa detrás de color de piel
relocate(height, mass, .after = skin_color)
## # A tibble: 87 × 14
## name hair_color skin_color height mass eye_color birth_year sex gender
## <chr> <chr> <chr> <int> <dbl> <chr> <dbl> <chr> <chr>
## 1 Luke S… blond fair 172 77 blue 19 male mascu…
## 2 C-3PO <NA> gold 167 75 yellow 112 none mascu…
## 3 R2-D2 <NA> white, bl… 96 32 red 33 none mascu…
## 4 Darth … none white 202 136 yellow 41.9 male mascu…
## 5 Leia O… brown light 150 49 brown 19 fema… femin…
## 6 Owen L… brown, grey light 178 120 blue 52 male mascu…
## 7 Beru W… brown light 165 75 blue 47 fema… femin…
## 8 R5-D4 <NA> white, red 97 32 red NA none mascu…
## 9 Biggs … black light 183 84 brown 24 male mascu…
## 10 Obi-Wa… auburn, wh… fair 182 77 blue-gray 57 male mascu…
## # … with 77 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
starwars %>% # color de piel, pelo y ojos antes de peso
relocate(hair_color, skin_color, eye_color,
.before = mass)
## # A tibble: 87 × 14
## name height hair_color skin_color eye_color mass birth_year sex gender
## <chr> <int> <chr> <chr> <chr> <dbl> <dbl> <chr> <chr>
## 1 Luke S… 172 blond fair blue 77 19 male mascu…
## 2 C-3PO 167 <NA> gold yellow 75 112 none mascu…
## 3 R2-D2 96 <NA> white, bl… red 32 33 none mascu…
## 4 Darth … 202 none white yellow 136 41.9 male mascu…
## 5 Leia O… 150 brown light brown 49 19 fema… femin…
## 6 Owen L… 178 brown, grey light blue 120 52 male mascu…
## 7 Beru W… 165 brown light blue 75 47 fema… femin…
## 8 R5-D4 97 <NA> white, red red 32 NA none mascu…
## 9 Biggs … 183 black light brown 84 24 male mascu…
## 10 Obi-Wa… 182 auburn, wh… fair blue-gray 77 57 male mascu…
## # … with 77 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
Otra opción es hacerlo con select()
, indicándole el orden de las columnas manualmente, pudiendo hacer uso de everything()
para incluir el resto de columnas no mencionadas anteriormente.
starwars %>% select(name, homeworld, everything())
## # A tibble: 87 × 14
## name homeworld height mass hair_color skin_color eye_color birth_year sex
## <chr> <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr>
## 1 Luke… Tatooine 172 77 blond fair blue 19 male
## 2 C-3PO Tatooine 167 75 <NA> gold yellow 112 none
## 3 R2-D2 Naboo 96 32 <NA> white, bl… red 33 none
## 4 Dart… Tatooine 202 136 none white yellow 41.9 male
## 5 Leia… Alderaan 150 49 brown light brown 19 fema…
## 6 Owen… Tatooine 178 120 brown, gr… light blue 52 male
## 7 Beru… Tatooine 165 75 brown light blue 47 fema…
## 8 R5-D4 Tatooine 97 32 <NA> white, red red NA none
## 9 Bigg… Tatooine 183 84 black light brown 24 male
## 10 Obi-… Stewjon 182 77 auburn, w… fair blue-gray 57 male
## # … with 77 more rows, and 5 more variables: gender <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
13.3 Crear nuevas variables (mutate)
A veces no queremos modificar variables ya existentes sino crear nuevas variables/columnas en base a variables ya existentes. Para ello tenemos la opción de mutate()
que nos permite crear una nueva variable en función de las existentes.
# Mutate: nos añade nuevas columnas usando funciones
# aplicadas a nuestras variables
starwars %>% mutate(height_m = height / 100) # altura en metros
## # A tibble: 87 × 15
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke S… 172 77 blond fair blue 19 male mascu…
## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 4 Darth … 202 136 none white yellow 41.9 male mascu…
## 5 Leia O… 150 49 brown light brown 19 fema… femin…
## 6 Owen L… 178 120 brown, grey light blue 52 male mascu…
## 7 Beru W… 165 75 brown light blue 47 fema… femin…
## 8 R5-D4 97 32 <NA> white, red red NA none mascu…
## 9 Biggs … 183 84 black light brown 24 male mascu…
## 10 Obi-Wa… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## # … with 77 more rows, and 6 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>, height_m <dbl>
Recuerda que para ver todas las columnas debes indicarle que quieres imprimir todas.
print(starwars %>% mutate(height_m = height / 100), width = Inf)
## # A tibble: 87 × 15
## name height mass hair_color skin_color eye_color
## <chr> <int> <dbl> <chr> <chr> <chr>
## 1 Luke Skywalker 172 77 blond fair blue
## 2 C-3PO 167 75 <NA> gold yellow
## 3 R2-D2 96 32 <NA> white, blue red
## 4 Darth Vader 202 136 none white yellow
## 5 Leia Organa 150 49 brown light brown
## 6 Owen Lars 178 120 brown, grey light blue
## 7 Beru Whitesun lars 165 75 brown light blue
## 8 R5-D4 97 32 <NA> white, red red
## 9 Biggs Darklighter 183 84 black light brown
## 10 Obi-Wan Kenobi 182 77 auburn, white fair blue-gray
## birth_year sex gender homeworld species films vehicles starships
## <dbl> <chr> <chr> <chr> <chr> <list> <list> <list>
## 1 19 male masculine Tatooine Human <chr [5]> <chr [2]> <chr [2]>
## 2 112 none masculine Tatooine Droid <chr [6]> <chr [0]> <chr [0]>
## 3 33 none masculine Naboo Droid <chr [7]> <chr [0]> <chr [0]>
## 4 41.9 male masculine Tatooine Human <chr [4]> <chr [0]> <chr [1]>
## 5 19 female feminine Alderaan Human <chr [5]> <chr [1]> <chr [0]>
## 6 52 male masculine Tatooine Human <chr [3]> <chr [0]> <chr [0]>
## 7 47 female feminine Tatooine Human <chr [3]> <chr [0]> <chr [0]>
## 8 NA none masculine Tatooine Droid <chr [1]> <chr [0]> <chr [0]>
## 9 24 male masculine Tatooine Human <chr [1]> <chr [0]> <chr [1]>
## 10 57 male masculine Stewjon Human <chr [6]> <chr [1]> <chr [5]>
## height_m
## <dbl>
## 1 1.72
## 2 1.67
## 3 0.96
## 4 2.02
## 5 1.5
## 6 1.78
## 7 1.65
## 8 0.97
## 9 1.83
## 10 1.82
## # … with 77 more rows
Otra opción es quedarnos solo con las columnas nuevas creadas con transmute()
starwars %>% transmute(height_m = height / 100)
## # A tibble: 87 × 1
## height_m
## <dbl>
## 1 1.72
## 2 1.67
## 3 0.96
## 4 2.02
## 5 1.5
## 6 1.78
## 7 1.65
## 8 0.97
## 9 1.83
## 10 1.82
## # … with 77 more rows
Si queremos añadir varias variables en función de las ya existentes podemos hacerlo ya que permite incorporar los datos de forma secuencial sin duplicar órdenes de mutate()
para cada una.
print(starwars %>%
# Calculamos altura en metros y el IMC
mutate(height_m = height / 100,
BMI = mass / (height_m^2)), width = Inf)
## # A tibble: 87 × 16
## name height mass hair_color skin_color eye_color
## <chr> <int> <dbl> <chr> <chr> <chr>
## 1 Luke Skywalker 172 77 blond fair blue
## 2 C-3PO 167 75 <NA> gold yellow
## 3 R2-D2 96 32 <NA> white, blue red
## 4 Darth Vader 202 136 none white yellow
## 5 Leia Organa 150 49 brown light brown
## 6 Owen Lars 178 120 brown, grey light blue
## 7 Beru Whitesun lars 165 75 brown light blue
## 8 R5-D4 97 32 <NA> white, red red
## 9 Biggs Darklighter 183 84 black light brown
## 10 Obi-Wan Kenobi 182 77 auburn, white fair blue-gray
## birth_year sex gender homeworld species films vehicles starships
## <dbl> <chr> <chr> <chr> <chr> <list> <list> <list>
## 1 19 male masculine Tatooine Human <chr [5]> <chr [2]> <chr [2]>
## 2 112 none masculine Tatooine Droid <chr [6]> <chr [0]> <chr [0]>
## 3 33 none masculine Naboo Droid <chr [7]> <chr [0]> <chr [0]>
## 4 41.9 male masculine Tatooine Human <chr [4]> <chr [0]> <chr [1]>
## 5 19 female feminine Alderaan Human <chr [5]> <chr [1]> <chr [0]>
## 6 52 male masculine Tatooine Human <chr [3]> <chr [0]> <chr [0]>
## 7 47 female feminine Tatooine Human <chr [3]> <chr [0]> <chr [0]>
## 8 NA none masculine Tatooine Droid <chr [1]> <chr [0]> <chr [0]>
## 9 24 male masculine Tatooine Human <chr [1]> <chr [0]> <chr [1]>
## 10 57 male masculine Stewjon Human <chr [6]> <chr [1]> <chr [5]>
## height_m BMI
## <dbl> <dbl>
## 1 1.72 26.0
## 2 1.67 26.9
## 3 0.96 34.7
## 4 2.02 33.3
## 5 1.5 21.8
## 6 1.78 37.9
## 7 1.65 27.5
## 8 0.97 34.0
## 9 1.83 25.1
## 10 1.82 23.2
## # … with 77 more rows
Como ves por defecto añade las columnas al final pero podemos reordenar las columnas como ya hemos visto
starwars %>%
mutate(height_m = height / 100,
BMI = mass / (height_m^2)) %>%
relocate(height_m, BMI, .after = name)
## # A tibble: 87 × 16
## name height_m BMI height mass hair_color skin_color eye_color birth_year
## <chr> <dbl> <dbl> <int> <dbl> <chr> <chr> <chr> <dbl>
## 1 Luke … 1.72 26.0 172 77 blond fair blue 19
## 2 C-3PO 1.67 26.9 167 75 <NA> gold yellow 112
## 3 R2-D2 0.96 34.7 96 32 <NA> white, bl… red 33
## 4 Darth… 2.02 33.3 202 136 none white yellow 41.9
## 5 Leia … 1.5 21.8 150 49 brown light brown 19
## 6 Owen … 1.78 37.9 178 120 brown, gr… light blue 52
## 7 Beru … 1.65 27.5 165 75 brown light blue 47
## 8 R5-D4 0.97 34.0 97 32 <NA> white, red red NA
## 9 Biggs… 1.83 25.1 183 84 black light brown 24
## 10 Obi-W… 1.82 23.2 182 77 auburn, w… fair blue-gray 57
## # … with 77 more rows, and 7 more variables: sex <chr>, gender <chr>,
## # homeworld <chr>, species <chr>, films <list>, vehicles <list>,
## # starships <list>
También podemos pasarle una función propia que queramos definir, no solo funciones de R
. Vamos a definir la función que nos calcula el IMC, a la que llamaremos BMI_fun
, que necesita solo de dos argumentos: la altura en metros y el peso.
BMI_fun <- function(m, h) {
return(m / h^2)
}
BMI_fun(90, 1.6)
## [1] 35.15625
La función definida como BMI_fun()
podemos ahora aplicarla dentro de mutate()
.
starwars %>%
mutate(height_m = height / 100,
BMI = BMI_fun(mass, height_m)) %>%
# Las movemos al inicio (por defecto las mete al final)
relocate(height_m, BMI, .after = name)
## # A tibble: 87 × 16
## name height_m BMI height mass hair_color skin_color eye_color birth_year
## <chr> <dbl> <dbl> <int> <dbl> <chr> <chr> <chr> <dbl>
## 1 Luke … 1.72 26.0 172 77 blond fair blue 19
## 2 C-3PO 1.67 26.9 167 75 <NA> gold yellow 112
## 3 R2-D2 0.96 34.7 96 32 <NA> white, bl… red 33
## 4 Darth… 2.02 33.3 202 136 none white yellow 41.9
## 5 Leia … 1.5 21.8 150 49 brown light brown 19
## 6 Owen … 1.78 37.9 178 120 brown, gr… light blue 52
## 7 Beru … 1.65 27.5 165 75 brown light blue 47
## 8 R5-D4 0.97 34.0 97 32 <NA> white, red red NA
## 9 Biggs… 1.83 25.1 183 84 black light brown 24
## 10 Obi-W… 1.82 23.2 182 77 auburn, w… fair blue-gray 57
## # … with 77 more rows, and 7 more variables: sex <chr>, gender <chr>,
## # homeworld <chr>, species <chr>, films <list>, vehicles <list>,
## # starships <list>
También se pueden aplicar funciones más complejas como la función map()
del paquete purrr para manejo de listas: dado que las listas no se pueden vectorizar, esta función nos permite aplicar operaciones a listas, elemento a elemento de cada una de ellas. Veamos un ejemplo: imagina que queremos calcular el número de películas en las que sale cada personaje de la saga.
# Películas de los 5 primeros personajes
starwars$films[1:5]
## [[1]]
## [1] "The Empire Strikes Back" "Revenge of the Sith"
## [3] "Return of the Jedi" "A New Hope"
## [5] "The Force Awakens"
##
## [[2]]
## [1] "The Empire Strikes Back" "Attack of the Clones"
## [3] "The Phantom Menace" "Revenge of the Sith"
## [5] "Return of the Jedi" "A New Hope"
##
## [[3]]
## [1] "The Empire Strikes Back" "Attack of the Clones"
## [3] "The Phantom Menace" "Revenge of the Sith"
## [5] "Return of the Jedi" "A New Hope"
## [7] "The Force Awakens"
##
## [[4]]
## [1] "The Empire Strikes Back" "Revenge of the Sith"
## [3] "Return of the Jedi" "A New Hope"
##
## [[5]]
## [1] "The Empire Strikes Back" "Revenge of the Sith"
## [3] "Return of the Jedi" "A New Hope"
## [5] "The Force Awakens"
Las películas de cada personaje están en modo lista: no podíamos guardarlo en un data.frame
ya que cada personaje ha podido participar en un número distinto (en una tabla, todas las columnas tienen la misma longitud). Para saber la cantidad de películas en las que ha participado el primer personaje basta con usar el comando length()
(nos dará el número de elementos de la lista).
length(starwars$films[1])
## [1] 1
¿Cómo aplicar dicha a función a cada personaje? Con map()
y la función a aplicar en cada elemento de la lista.
# Mapeamos la lista con length
(starwars$films %>% map(length))[1:10]
## [[1]]
## [1] 5
##
## [[2]]
## [1] 6
##
## [[3]]
## [1] 7
##
## [[4]]
## [1] 4
##
## [[5]]
## [1] 5
##
## [[6]]
## [1] 3
##
## [[7]]
## [1] 3
##
## [[8]]
## [1] 1
##
## [[9]]
## [1] 1
##
## [[10]]
## [1] 6
Si te fijas con los 10 primeros, lo que nos devuelve por defecto a su vez una lista, cuando a nosotros nos gustaría que nos devolviera un vector que poder incluir como columna. Para ello existen diversas funciones como map_chr()
, map_dbl()
para devolverlo en un formato concreto (caracter o numérico).
# Mapeamos la lista con length pero devolvemos un vector de números enteros
starwars$films %>% map_int(length)
## [1] 5 6 7 4 5 3 3 1 1 6 3 2 5 4 1 3 3 1 5 5 3 1 1 2 1 2 1 1 1 1 1 3 1 2 1 1 1 2
## [39] 1 1 2 1 1 3 1 1 1 3 3 3 2 2 2 1 3 2 1 1 1 2 2 1 1 2 2 1 1 1 1 1 1 1 2 1 1 2
## [77] 1 1 2 2 1 1 1 1 1 1 3
Ya solo nos falta incorporar dicha operación a una nueva columna con mutate()
starwars %>%
mutate("n_peliculas" = map_int(films, length)) %>%
select(c(name, homeworld, n_peliculas))
## # A tibble: 87 × 3
## name homeworld n_peliculas
## <chr> <chr> <int>
## 1 Luke Skywalker Tatooine 5
## 2 C-3PO Tatooine 6
## 3 R2-D2 Naboo 7
## 4 Darth Vader Tatooine 4
## 5 Leia Organa Alderaan 5
## 6 Owen Lars Tatooine 3
## 7 Beru Whitesun lars Tatooine 3
## 8 R5-D4 Tatooine 1
## 9 Biggs Darklighter Tatooine 1
## 10 Obi-Wan Kenobi Stewjon 6
## # … with 77 more rows
13.3.1 Recategorizar columnas
Una operación también muy habitual es querer recategorizar nuestras variables: tenemos categorías ya existentes o variables numéricas que queremos convertir a categoría (factores en R
). Supongamos por ejemplo que queremos crear una categoría para cada registro en función de su altura: menos de 120, entre 120 y 180, y más de 180. Para ello podemos hacer uso de la función cut()
, a la que en el argumento breaks
le debemos indicar los «cortes» o saltos de la variable.
print(starwars %>% mutate("estat_categoria" = cut(height, breaks = c(-Inf, 120, 180, Inf))), width = Inf)
## # A tibble: 87 × 15
## name height mass hair_color skin_color eye_color
## <chr> <int> <dbl> <chr> <chr> <chr>
## 1 Luke Skywalker 172 77 blond fair blue
## 2 C-3PO 167 75 <NA> gold yellow
## 3 R2-D2 96 32 <NA> white, blue red
## 4 Darth Vader 202 136 none white yellow
## 5 Leia Organa 150 49 brown light brown
## 6 Owen Lars 178 120 brown, grey light blue
## 7 Beru Whitesun lars 165 75 brown light blue
## 8 R5-D4 97 32 <NA> white, red red
## 9 Biggs Darklighter 183 84 black light brown
## 10 Obi-Wan Kenobi 182 77 auburn, white fair blue-gray
## birth_year sex gender homeworld species films vehicles starships
## <dbl> <chr> <chr> <chr> <chr> <list> <list> <list>
## 1 19 male masculine Tatooine Human <chr [5]> <chr [2]> <chr [2]>
## 2 112 none masculine Tatooine Droid <chr [6]> <chr [0]> <chr [0]>
## 3 33 none masculine Naboo Droid <chr [7]> <chr [0]> <chr [0]>
## 4 41.9 male masculine Tatooine Human <chr [4]> <chr [0]> <chr [1]>
## 5 19 female feminine Alderaan Human <chr [5]> <chr [1]> <chr [0]>
## 6 52 male masculine Tatooine Human <chr [3]> <chr [0]> <chr [0]>
## 7 47 female feminine Tatooine Human <chr [3]> <chr [0]> <chr [0]>
## 8 NA none masculine Tatooine Droid <chr [1]> <chr [0]> <chr [0]>
## 9 24 male masculine Tatooine Human <chr [1]> <chr [0]> <chr [1]>
## 10 57 male masculine Stewjon Human <chr [6]> <chr [1]> <chr [5]>
## estat_categoria
## <fct>
## 1 (120,180]
## 2 (120,180]
## 3 (-Inf,120]
## 4 (180, Inf]
## 5 (120,180]
## 6 (120,180]
## 7 (120,180]
## 8 (-Inf,120]
## 9 (180, Inf]
## 10 (180, Inf]
## # … with 77 more rows
Recuerda que si quieres mostrar solo las nuevas columnas creadas puedes usar transmute()
## # A tibble: 87 × 1
## estat_categoria
## <fct>
## 1 (120,180]
## 2 (120,180]
## 3 (-Inf,120]
## 4 (180, Inf]
## 5 (120,180]
## 6 (120,180]
## 7 (120,180]
## 8 (-Inf,120]
## 9 (180, Inf]
## 10 (180, Inf]
## # … with 77 more rows
Si queremos que la categoría tenga un nombre explícito (y no el intervalo en sí), podemos indicárselo en labels =
el vector de nombres de las categorías.
starwars %>%
transmute("estat_categoria" = cut(height, breaks = c(-Inf, 120, 180, Inf),
labels = c("bajos", "medios", "altos")))
## # A tibble: 87 × 1
## estat_categoria
## <fct>
## 1 medios
## 2 medios
## 3 bajos
## 4 altos
## 5 medios
## 6 medios
## 7 medios
## 8 bajos
## 9 altos
## 10 altos
## # … with 77 more rows
Otra opción es hacerlo con la función factor
que nos transforma una variable en categoría.
# Vamos a categorizar en bajitos a los que miden menos de 180 cm
starwars %>%
mutate(talla = factor(height < 180, labels = c("bajos", "altos")))
## # A tibble: 87 × 15
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke S… 172 77 blond fair blue 19 male mascu…
## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 4 Darth … 202 136 none white yellow 41.9 male mascu…
## 5 Leia O… 150 49 brown light brown 19 fema… femin…
## 6 Owen L… 178 120 brown, grey light blue 52 male mascu…
## 7 Beru W… 165 75 brown light blue 47 fema… femin…
## 8 R5-D4 97 32 <NA> white, red red NA none mascu…
## 9 Biggs … 183 84 black light brown 24 male mascu…
## 10 Obi-Wa… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## # … with 77 more rows, and 6 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>, talla <fct>
13.4 Datos ausentes y outliers
Como ya vimos en Tipos de datos I: vectores, los datos ausentes en R
pueden venir representados por valores NA
o por valores NaN
(en realidad este no sería ausente siendo estrictos, es simplemente un resultado no numérico dentro de los reales). ¿Qué hacer con dichos valores?
Una primera opción puede ser eliminar los registros que contengan campos ausentes en alguna de sus variables, haciendo uso de la función drop_na()
.
starwars %>% drop_na()
## # A tibble: 6 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke Sk… 172 77 blond fair blue 19 male mascu…
## 2 Obi-Wan… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## 3 Anakin … 188 84 blond fair blue 41.9 male mascu…
## 4 Chewbac… 228 112 brown unknown blue 200 male mascu…
## 5 Wedge A… 170 77 brown fair hazel 21 male mascu…
## 6 Darth M… 175 80 none red yellow 54 male mascu…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
Como ves solo 6 de los 87 registros tienen todos los campos completos. Como quizás no todos los campos sean igual de importantes en nuestros, podemos indicarle que nos elimine aquellos registros que tengan datos ausentes algunos campos en concreto (o una coelcción de ellos)
starwars %>% drop_na(mass, height, sex, gender, birth_year)
## # A tibble: 36 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke S… 172 77 blond fair blue 19 male mascu…
## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 4 Darth … 202 136 none white yellow 41.9 male mascu…
## 5 Leia O… 150 49 brown light brown 19 fema… femin…
## 6 Owen L… 178 120 brown, grey light blue 52 male mascu…
## 7 Beru W… 165 75 brown light blue 47 fema… femin…
## 8 Biggs … 183 84 black light brown 24 male mascu…
## 9 Obi-Wa… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## 10 Anakin… 188 84 blond fair blue 41.9 male mascu…
## # … with 26 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
Otra opción es imputar su valor en el caso de variables cuantitativas por, por ejemplo, la media de la variable sin datos ausentes, y recategorizar las cuantitaivas creando un categoría per se de ausentes.
starwars %>%
# Variables cuanti
mutate(across(where(is.numeric),
~replace(.x, is.na(.x), mean(.x, na.rm = TRUE)))) %>%
# Variables cuali: pasamos NA y "none" a "unknown"
mutate(across(where(is.character),
~replace(.x, is.na(.x) | .x == "none", "unknown")))
## # A tibble: 87 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <dbl> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke S… 172 77 blond fair blue 19 male mascu…
## 2 C-3PO 167 75 unknown gold yellow 112 unkn… mascu…
## 3 R2-D2 96 32 unknown white, bl… red 33 unkn… mascu…
## 4 Darth … 202 136 unknown white yellow 41.9 male mascu…
## 5 Leia O… 150 49 brown light brown 19 fema… femin…
## 6 Owen L… 178 120 brown, grey light blue 52 male mascu…
## 7 Beru W… 165 75 brown light blue 47 fema… femin…
## 8 R5-D4 97 32 unknown white, red red 87.6 unkn… mascu…
## 9 Biggs … 183 84 black light brown 24 male mascu…
## 10 Obi-Wa… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## # … with 77 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
Muchas veces tendremos variables con valores muy alejados de la centralidad, centralidad normalmente entendida como media o mediana, valores muy extremos (conocidos como valores atípicos o outliers).
Respecto a la mediana/percentiles (iqr): una definición de outlier muy habitual es definirlo como un valor muy alejado del primer/tercer cuartil. La definición que se suele usar es que el dato sea interior/superior al primer/tercer cuartil una amplitud de X veces el rango intercuartílico (conocido como IQR, calculado como el tercer cuartil menos el primer cuartil) por debajo/encima.
Respecto a la media (gesd): el criterio utilizado suele ser el conocido como GESD (Generlized Extreme Studentized Deviate Test), un contraste de hipótesis cuya hipótesis nula es que no hay atípicos en los datos. Puedes ver la formulación matemática en https://www.itl.nist.gov/div898/handbook/eda/section3/eda35h3.htm
Para su localización automática usaremos el paquete anomalize, y la función homónima de dicho paquete, indicándole la columna individual en la que queremos detectar outliers y el método a usar. Con el método method = "gesd"
realizaremos el contraste dato a dato de forma secuencial (si hay outlier lo quita individualmente y vuelve a ejecutarlo). Con method = "iqr"
, ese factor X
que nos distanciamos del primer y tercer cuartil es calculado como 0.15/alpha
, de forma que con alpha = 0.05
(por ejemplo), dicho factor sería X = 3
. Es MUY IMPORTANTE quitar antes los valores ausentes (para que pueda ejecutarse correctamente).
library(anomalize)
# Importante: quitar antes missings
starwars %>% drop_na(mass) %>% anomalize(mass, method = "gesd")
## # A tibble: 59 × 17
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke S… 172 77 blond fair blue 19 male mascu…
## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 4 Darth … 202 136 none white yellow 41.9 male mascu…
## 5 Leia O… 150 49 brown light brown 19 fema… femin…
## 6 Owen L… 178 120 brown, grey light blue 52 male mascu…
## 7 Beru W… 165 75 brown light blue 47 fema… femin…
## 8 R5-D4 97 32 <NA> white, red red NA none mascu…
## 9 Biggs … 183 84 black light brown 24 male mascu…
## 10 Obi-Wa… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## # … with 49 more rows, and 8 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>, mass_l1 <dbl>,
## # mass_l2 <dbl>, anomaly <chr>
En las columnas mass_l1
y mass_l2
se nos han guardado los límites para considerar o no outlier, y en anomaly
tendremos si el valor es un outlier o no. Podemos renombrar dicha columna y recategorizarlo con TRUE/FALSE
print(starwars %>%
drop_na(mass) %>%
anomalize(mass, method = "gesd") %>%
rename(outlier = anomaly) %>%
# Eliminamos la variables auxiliares creadas
select(-c(mass_l1, mass_l2)) %>%
mutate(outlier = (outlier == "Yes")), width = Inf)
## # A tibble: 59 × 15
## name height mass hair_color skin_color eye_color
## <chr> <int> <dbl> <chr> <chr> <chr>
## 1 Luke Skywalker 172 77 blond fair blue
## 2 C-3PO 167 75 <NA> gold yellow
## 3 R2-D2 96 32 <NA> white, blue red
## 4 Darth Vader 202 136 none white yellow
## 5 Leia Organa 150 49 brown light brown
## 6 Owen Lars 178 120 brown, grey light blue
## 7 Beru Whitesun lars 165 75 brown light blue
## 8 R5-D4 97 32 <NA> white, red red
## 9 Biggs Darklighter 183 84 black light brown
## 10 Obi-Wan Kenobi 182 77 auburn, white fair blue-gray
## birth_year sex gender homeworld species films vehicles starships
## <dbl> <chr> <chr> <chr> <chr> <list> <list> <list>
## 1 19 male masculine Tatooine Human <chr [5]> <chr [2]> <chr [2]>
## 2 112 none masculine Tatooine Droid <chr [6]> <chr [0]> <chr [0]>
## 3 33 none masculine Naboo Droid <chr [7]> <chr [0]> <chr [0]>
## 4 41.9 male masculine Tatooine Human <chr [4]> <chr [0]> <chr [1]>
## 5 19 female feminine Alderaan Human <chr [5]> <chr [1]> <chr [0]>
## 6 52 male masculine Tatooine Human <chr [3]> <chr [0]> <chr [0]>
## 7 47 female feminine Tatooine Human <chr [3]> <chr [0]> <chr [0]>
## 8 NA none masculine Tatooine Droid <chr [1]> <chr [0]> <chr [0]>
## 9 24 male masculine Tatooine Human <chr [1]> <chr [0]> <chr [1]>
## 10 57 male masculine Stewjon Human <chr [6]> <chr [1]> <chr [5]>
## outlier
## <lgl>
## 1 FALSE
## 2 FALSE
## 3 TRUE
## 4 TRUE
## 5 FALSE
## 6 TRUE
## 7 FALSE
## 8 FALSE
## 9 FALSE
## 10 FALSE
## # … with 49 more rows
Dicha variable auxiliar la podremos usar para decidir si incluir o no el registro en futuros pasos, pero también podemos usarla para imputarle un valor (por ejemplo, la media).
print(starwars %>%
drop_na(mass) %>%
anomalize(mass, method = "gesd") %>%
rename(outlier = anomaly) %>%
# Eliminamos la variables auxiliares creadas
select(-c(mass_l1, mass_l2)) %>%
mutate(outlier = (outlier == "Yes"),
mass = ifelse(outlier, mean(mass), mass)),
width = Inf)
## # A tibble: 59 × 15
## name height mass hair_color skin_color eye_color
## <chr> <int> <dbl> <chr> <chr> <chr>
## 1 Luke Skywalker 172 77 blond fair blue
## 2 C-3PO 167 75 <NA> gold yellow
## 3 R2-D2 96 97.3 <NA> white, blue red
## 4 Darth Vader 202 97.3 none white yellow
## 5 Leia Organa 150 49 brown light brown
## 6 Owen Lars 178 97.3 brown, grey light blue
## 7 Beru Whitesun lars 165 75 brown light blue
## 8 R5-D4 97 32 <NA> white, red red
## 9 Biggs Darklighter 183 84 black light brown
## 10 Obi-Wan Kenobi 182 77 auburn, white fair blue-gray
## birth_year sex gender homeworld species films vehicles starships
## <dbl> <chr> <chr> <chr> <chr> <list> <list> <list>
## 1 19 male masculine Tatooine Human <chr [5]> <chr [2]> <chr [2]>
## 2 112 none masculine Tatooine Droid <chr [6]> <chr [0]> <chr [0]>
## 3 33 none masculine Naboo Droid <chr [7]> <chr [0]> <chr [0]>
## 4 41.9 male masculine Tatooine Human <chr [4]> <chr [0]> <chr [1]>
## 5 19 female feminine Alderaan Human <chr [5]> <chr [1]> <chr [0]>
## 6 52 male masculine Tatooine Human <chr [3]> <chr [0]> <chr [0]>
## 7 47 female feminine Tatooine Human <chr [3]> <chr [0]> <chr [0]>
## 8 NA none masculine Tatooine Droid <chr [1]> <chr [0]> <chr [0]>
## 9 24 male masculine Tatooine Human <chr [1]> <chr [0]> <chr [1]>
## 10 57 male masculine Stewjon Human <chr [6]> <chr [1]> <chr [5]>
## outlier
## <lgl>
## 1 FALSE
## 2 FALSE
## 3 TRUE
## 4 TRUE
## 5 FALSE
## 6 TRUE
## 7 FALSE
## 8 FALSE
## 9 FALSE
## 10 FALSE
## # … with 49 more rows
13.5 Visualizar el procesamiento en tidyverse
Antes de pasar a los ejercicios, existe una reciente herramienta que nos va a permitir entender mejor y visualizar el flujo de trabajo de las funciones que hemos visto en este entorno tidyverse: https://tidydatatutor.com/. Basta con poner el código que queremos ejecutar, y nos muestra las operaciones en los datos visualmente.

Imagen/gráfica 13.2: Tidytutor.

Imagen/gráfica 13.3: Tidytutor.

Imagen/gráfica 13.4: Tidytutor.

Imagen/gráfica 13.5: Tidytutor.

Imagen/gráfica 13.6: Tidytutor.

Imagen/gráfica 13.7: Tidytutor.
13.6 📝 Ejercicios
(haz click en las flechas para ver soluciones)
📝Ejercicio 1: del fichero
starwars
encuentra todos los personajes que el peso esté entre 60 y 90.
- Solución:
## # A tibble: 32 × 14
## name height mass hair_color skin_color eye_color birth_year
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl>
## 1 Luke Skywalker 172 77 blond fair blue 19
## 2 C-3PO 167 75 <NA> gold yellow 112
## 3 Beru Whitesun lars 165 75 brown light blue 47
## 4 Biggs Darklighter 183 84 black light brown 24
## 5 Obi-Wan Kenobi 182 77 auburn, white fair blue-gray 57
## 6 Anakin Skywalker 188 84 blond fair blue 41.9
## 7 Han Solo 180 80 brown fair brown 29
## 8 Greedo 173 74 <NA> green black 44
## 9 Wedge Antilles 170 77 brown fair hazel 21
## 10 Palpatine 170 75 grey pale yellow 82
## sex gender homeworld species films vehicles starships
## <chr> <chr> <chr> <chr> <list> <list> <list>
## 1 male masculine Tatooine Human <chr [5]> <chr [2]> <chr [2]>
## 2 none masculine Tatooine Droid <chr [6]> <chr [0]> <chr [0]>
## 3 female feminine Tatooine Human <chr [3]> <chr [0]> <chr [0]>
## 4 male masculine Tatooine Human <chr [1]> <chr [0]> <chr [1]>
## 5 male masculine Stewjon Human <chr [6]> <chr [1]> <chr [5]>
## 6 male masculine Tatooine Human <chr [3]> <chr [2]> <chr [3]>
## 7 male masculine Corellia Human <chr [4]> <chr [0]> <chr [2]>
## 8 male masculine Rodia Rodian <chr [1]> <chr [0]> <chr [0]>
## 9 male masculine Corellia Human <chr [3]> <chr [1]> <chr [1]>
## 10 male masculine Naboo Human <chr [5]> <chr [0]> <chr [0]>
## # … with 22 more rows
📝Ejercicio 2: añadido al filtro anterior, encuentra todos los personajes de ojos que no sean azules, y que tengan menos de 100 años.
- Solución:
# todas columnas
filtro <-
starwars %>%
filter(between(mass, 60, 90) & eye_color != "blue" &
birth_year < 100)
print(filtro, width = Inf)
## # A tibble: 15 × 14
## name height mass hair_color skin_color eye_color
## <chr> <int> <dbl> <chr> <chr> <chr>
## 1 Biggs Darklighter 183 84 black light brown
## 2 Obi-Wan Kenobi 182 77 auburn, white fair blue-gray
## 3 Han Solo 180 80 brown fair brown
## 4 Greedo 173 74 <NA> green black
## 5 Wedge Antilles 170 77 brown fair hazel
## 6 Palpatine 170 75 grey pale yellow
## 7 Boba Fett 183 78.2 black fair brown
## 8 Lando Calrissian 177 79 black dark brown
## 9 Ackbar 180 83 none brown mottle orange
## 10 Jar Jar Binks 196 66 none orange orange
## 11 Darth Maul 175 80 none red yellow
## 12 Mace Windu 188 84 none dark brown
## 13 Ki-Adi-Mundi 198 82 white pale yellow
## 14 Plo Koon 188 80 none orange black
## 15 Jango Fett 183 79 black tan brown
## birth_year sex gender homeworld species films vehicles
## <dbl> <chr> <chr> <chr> <chr> <list> <list>
## 1 24 male masculine Tatooine Human <chr [1]> <chr [0]>
## 2 57 male masculine Stewjon Human <chr [6]> <chr [1]>
## 3 29 male masculine Corellia Human <chr [4]> <chr [0]>
## 4 44 male masculine Rodia Rodian <chr [1]> <chr [0]>
## 5 21 male masculine Corellia Human <chr [3]> <chr [1]>
## 6 82 male masculine Naboo Human <chr [5]> <chr [0]>
## 7 31.5 male masculine Kamino Human <chr [3]> <chr [0]>
## 8 31 male masculine Socorro Human <chr [2]> <chr [0]>
## 9 41 male masculine Mon Cala Mon Calamari <chr [2]> <chr [0]>
## 10 52 male masculine Naboo Gungan <chr [2]> <chr [0]>
## 11 54 male masculine Dathomir Zabrak <chr [1]> <chr [1]>
## 12 72 male masculine Haruun Kal Human <chr [3]> <chr [0]>
## 13 92 male masculine Cerea Cerean <chr [3]> <chr [0]>
## 14 22 male masculine Dorin Kel Dor <chr [3]> <chr [0]>
## 15 66 male masculine Concord Dawn Human <chr [1]> <chr [0]>
## starships
## <list>
## 1 <chr [1]>
## 2 <chr [5]>
## 3 <chr [2]>
## 4 <chr [0]>
## 5 <chr [1]>
## 6 <chr [0]>
## 7 <chr [1]>
## 8 <chr [1]>
## 9 <chr [0]>
## 10 <chr [0]>
## 11 <chr [1]>
## 12 <chr [0]>
## 13 <chr [0]>
## 14 <chr [1]>
## 15 <chr [0]>
📝Ejercicio 3: añadido al filtro anterior, selecciona solo las columnas
name, mass, eye_color, birth_year
- Solución:
# Solo name, mass, eye_color, birth_year
filtro %>% select(c(name, mass, eye_color, birth_year))
## # A tibble: 15 × 4
## name mass eye_color birth_year
## <chr> <dbl> <chr> <dbl>
## 1 Biggs Darklighter 84 brown 24
## 2 Obi-Wan Kenobi 77 blue-gray 57
## 3 Han Solo 80 brown 29
## 4 Greedo 74 black 44
## 5 Wedge Antilles 77 hazel 21
## 6 Palpatine 75 yellow 82
## 7 Boba Fett 78.2 brown 31.5
## 8 Lando Calrissian 79 brown 31
## 9 Ackbar 83 orange 41
## 10 Jar Jar Binks 66 orange 52
## 11 Darth Maul 80 yellow 54
## 12 Mace Windu 84 brown 72
## 13 Ki-Adi-Mundi 82 yellow 92
## 14 Plo Koon 80 black 22
## 15 Jango Fett 79 brown 66
📝Ejercicio 4: selecciona solo las columnas que contengan variables numéricas, coloca los años de nacimiento como primera columna y cambia los nombres a castellano.
- Solución:
starwars %>% select(where(is.numeric))
## # A tibble: 87 × 3
## height mass birth_year
## <int> <dbl> <dbl>
## 1 172 77 19
## 2 167 75 112
## 3 96 32 33
## 4 202 136 41.9
## 5 150 49 19
## 6 178 120 52
## 7 165 75 47
## 8 97 32 NA
## 9 183 84 24
## 10 182 77 57
## # … with 77 more rows
📝Ejercicio 5: añadido a la selección anterior, coloca los años de nacimiento como primera columna y cambia los nombres a castellano.
- Solución:
starwars %>% select(where(is.numeric)) %>%
relocate(height, mass, .after = birth_year) %>%
rename(edad = birth_year, altura = height, peso = mass)
## # A tibble: 87 × 3
## edad altura peso
## <dbl> <int> <dbl>
## 1 19 172 77
## 2 112 167 75
## 3 33 96 32
## 4 41.9 202 136
## 5 19 150 49
## 6 52 178 120
## 7 47 165 75
## 8 NA 97 32
## 9 24 183 84
## 10 57 182 77
## # … with 77 more rows
📝Ejercicio 6: calcula una nueva columna que indique el número de naves que ha pilotado cada persona (escribe
? starwars
en consola para ver documentación del fichero).
- Solución:
starwars_numero_naves <-
starwars %>%
mutate(n_naves = map_chr(starships, length))
# Imprimimos todas las columnas
print(starwars_numero_naves, width = Inf)
## # A tibble: 87 × 15
## name height mass hair_color skin_color eye_color
## <chr> <int> <dbl> <chr> <chr> <chr>
## 1 Luke Skywalker 172 77 blond fair blue
## 2 C-3PO 167 75 <NA> gold yellow
## 3 R2-D2 96 32 <NA> white, blue red
## 4 Darth Vader 202 136 none white yellow
## 5 Leia Organa 150 49 brown light brown
## 6 Owen Lars 178 120 brown, grey light blue
## 7 Beru Whitesun lars 165 75 brown light blue
## 8 R5-D4 97 32 <NA> white, red red
## 9 Biggs Darklighter 183 84 black light brown
## 10 Obi-Wan Kenobi 182 77 auburn, white fair blue-gray
## birth_year sex gender homeworld species films vehicles starships
## <dbl> <chr> <chr> <chr> <chr> <list> <list> <list>
## 1 19 male masculine Tatooine Human <chr [5]> <chr [2]> <chr [2]>
## 2 112 none masculine Tatooine Droid <chr [6]> <chr [0]> <chr [0]>
## 3 33 none masculine Naboo Droid <chr [7]> <chr [0]> <chr [0]>
## 4 41.9 male masculine Tatooine Human <chr [4]> <chr [0]> <chr [1]>
## 5 19 female feminine Alderaan Human <chr [5]> <chr [1]> <chr [0]>
## 6 52 male masculine Tatooine Human <chr [3]> <chr [0]> <chr [0]>
## 7 47 female feminine Tatooine Human <chr [3]> <chr [0]> <chr [0]>
## 8 NA none masculine Tatooine Droid <chr [1]> <chr [0]> <chr [0]>
## 9 24 male masculine Tatooine Human <chr [1]> <chr [0]> <chr [1]>
## 10 57 male masculine Stewjon Human <chr [6]> <chr [1]> <chr [5]>
## n_naves
## <chr>
## 1 2
## 2 0
## 3 0
## 4 1
## 5 0
## 6 0
## 7 0
## 8 0
## 9 1
## 10 5
## # … with 77 more rows
# Solo la columna añadida
starwars %>%
transmute(n_naves = map_chr(starships, length))
## # A tibble: 87 × 1
## n_naves
## <chr>
## 1 2
## 2 0
## 3 0
## 4 1
## 5 0
## 6 0
## 7 0
## 8 0
## 9 1
## 10 5
## # … with 77 more rows
📝Ejercicio 7: con la columna anterior añadido, crea una nueva variable
TRUE/FALSE
que nos diga si ha conducido o no alguna nave, y filtra después solo aquellos personajes que han conducido alguna nave.
- Solución:
# Nueva columna lógica
starwars_numero_naves %>%
mutate(conducir_nave = n_naves > 0) %>%
filter(conducir_nave)
## # A tibble: 20 × 16
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke S… 172 77 blond fair blue 19 male mascu…
## 2 Darth … 202 136 none white yellow 41.9 male mascu…
## 3 Biggs … 183 84 black light brown 24 male mascu…
## 4 Obi-Wa… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## 5 Anakin… 188 84 blond fair blue 41.9 male mascu…
## 6 Chewba… 228 112 brown unknown blue 200 male mascu…
## 7 Han So… 180 80 brown fair brown 29 male mascu…
## 8 Wedge … 170 77 brown fair hazel 21 male mascu…
## 9 Jek To… 180 110 brown fair blue NA male mascu…
## 10 Boba F… 183 78.2 black fair brown 31.5 male mascu…
## 11 Lando … 177 79 black dark brown 31 male mascu…
## 12 Arvel … NA NA brown fair brown NA male mascu…
## 13 Nien N… 160 68 none grey black NA male mascu…
## 14 Ric Ol… 183 NA brown fair blue NA <NA> <NA>
## 15 Darth … 175 80 none red yellow 54 male mascu…
## 16 Plo Ko… 188 80 none orange black 22 male mascu…
## 17 Gregar… 185 85 black dark brown NA male mascu…
## 18 Grievo… 216 159 none brown, wh… green, y… NA male mascu…
## 19 Poe Da… NA NA brown light brown NA male mascu…
## 20 Padmé … 165 45 brown light brown 46 fema… femin…
## # … with 7 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>, n_naves <chr>, conducir_nave <lgl>
📝Ejercicio 8: calcula el número de películas en las que han salido y ordena a los personajes de mayor a menor número de películas en las que ha aparecido
- Solución:
starwars %>% # Calculamos primero el número de películas
mutate(n_films = map_int(films, length)) %>%
arrange(desc(n_films)) # Ordenamos de mayor a menor
## # A tibble: 87 × 15
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 3 Obi-Wa… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## 4 Luke S… 172 77 blond fair blue 19 male mascu…
## 5 Leia O… 150 49 brown light brown 19 fema… femin…
## 6 Chewba… 228 112 brown unknown blue 200 male mascu…
## 7 Yoda 66 17 white green brown 896 male mascu…
## 8 Palpat… 170 75 grey pale yellow 82 male mascu…
## 9 Darth … 202 136 none white yellow 41.9 male mascu…
## 10 Han So… 180 80 brown fair brown 29 male mascu…
## # … with 77 more rows, and 6 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>, n_films <int>
📝Ejercicio 9: selecciona 9 personajes al azar.
- Solución:
# Una extracción aleatoria
starwars %>% slice_sample(n = 9)
## # A tibble: 9 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Dooku 193 80 white fair brown 102 male mascu…
## 2 Greedo 173 74 <NA> green black 44 male mascu…
## 3 Gasgano 122 NA none white, bl… black NA male mascu…
## 4 Finis Va… 170 NA blond fair blue 91 male mascu…
## 5 Wicket S… 88 20 brown brown brown 8 male mascu…
## 6 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 7 Lando Ca… 177 79 black dark brown 31 male mascu…
## 8 Mace Win… 188 84 none dark brown 72 male mascu…
## 9 Bib Fort… 180 NA none pale pink NA male mascu…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
# otra (que sale distinta, claro)
starwars %>% slice_sample(n = 9)
## # A tibble: 9 × 14
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Eeth Ko… 171 NA black brown brown NA male mascu…
## 2 R2-D2 96 32 <NA> white, blue red 33 none mascu…
## 3 Kit Fis… 196 87 none green black NA male mascu…
## 4 Jango F… 183 79 black tan brown 66 male mascu…
## 5 Luke Sk… 172 77 blond fair blue 19 male mascu…
## 6 Tion Me… 206 80 none grey black NA male mascu…
## 7 Dexter … 198 102 none brown yellow NA male mascu…
## 8 R5-D4 97 32 <NA> white, red red NA none mascu…
## 9 Taun We 213 NA none grey black NA fema… femin…
## # … with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>
📝Ejercicio 10: de la tabla del ejercicio anterior, selecciona los 5 personajes que en más películas han salido y los 5 que menos.
- Solución:
# Una extracción aleatoria
selec_aleatoria <- starwars %>% slice_sample(n = 9)
# personajes que en más películas han salido (metiendo empates)
selec_aleatoria %>%
mutate(n_films = map_int(films, length)) %>%
slice_max(n_films, n = 5)
## # A tibble: 9 × 15
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Yoda 66 17 white green brown 896 male mascu…
## 2 Beru W… 165 75 brown light blue 47 fema… femin…
## 3 Nute G… 191 90 none mottled gre… red NA male mascu…
## 4 Padmé … 165 45 brown light brown 46 fema… femin…
## 5 Biggs … 183 84 black light brown 24 male mascu…
## 6 Gasgano 122 NA none white, blue black NA male mascu…
## 7 Ben Qu… 163 65 none grey, green… orange NA male mascu…
## 8 Grievo… 216 159 none brown, white green, y… NA male mascu…
## 9 Mon Mo… 150 NA auburn fair blue 48 fema… femin…
## # … with 6 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>, n_films <int>
# personajes que en más películas han salido (sin empates)
starwars %>%
mutate(n_films = map_int(films, length)) %>%
slice_max(n_films, n = 5, with_ties = FALSE)
## # A tibble: 5 × 15
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
## 2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
## 3 Obi-Wan… 182 77 auburn, wh… fair blue-gray 57 male mascu…
## 4 Luke Sk… 172 77 blond fair blue 19 male mascu…
## 5 Leia Or… 150 49 brown light brown 19 fema… femin…
## # … with 6 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>, n_films <int>
# personajes que en menos películas han salido (metiendo empates)
starwars %>%
mutate(n_films = map_int(films, length)) %>%
slice_min(n_films, n = 5)
## # A tibble: 46 × 15
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 R5-D4 97 32 <NA> white, red red NA none mascu…
## 2 Biggs D… 183 84 black light brown 24 male mascu…
## 3 Greedo 173 74 <NA> green black 44 male mascu…
## 4 Jek Ton… 180 110 brown fair blue NA male mascu…
## 5 IG-88 200 140 none metal red 15 none mascu…
## 6 Bossk 190 113 none green red 53 male mascu…
## 7 Lobot 175 79 none light blue 37 male mascu…
## 8 Mon Mot… 150 NA auburn fair blue 48 fema… femin…
## 9 Arvel C… NA NA brown fair brown NA male mascu…
## 10 Wicket … 88 20 brown brown brown 8 male mascu…
## # … with 36 more rows, and 6 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>, n_films <int>
# personajes que en menos películas han salido (sin empates)
starwars %>%
mutate(n_films = map_int(films, length)) %>%
slice_min(n_films, n = 5, with_ties = FALSE)
## # A tibble: 5 × 15
## name height mass hair_color skin_color eye_color birth_year sex gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 R5-D4 97 32 <NA> white, red red NA none mascu…
## 2 Biggs Da… 183 84 black light brown 24 male mascu…
## 3 Greedo 173 74 <NA> green black 44 male mascu…
## 4 Jek Tono… 180 110 brown fair blue NA male mascu…
## 5 IG-88 200 140 none metal red 15 none mascu…
## # … with 6 more variables: homeworld <chr>, species <chr>, films <list>,
## # vehicles <list>, starships <list>, n_films <int>
📝Ejercicio 11: selecciona las columnas que se refieren a variables de color (ojos, piel, pelo).
- Solución:
# Contiene "color" independientemente de que sea sufijo o prefijo
starwars %>% select(contains("color"))
## # A tibble: 87 × 3
## hair_color skin_color eye_color
## <chr> <chr> <chr>
## 1 blond fair blue
## 2 <NA> gold yellow
## 3 <NA> white, blue red
## 4 none white yellow
## 5 brown light brown
## 6 brown, grey light blue
## 7 brown light blue
## 8 <NA> white, red red
## 9 black light brown
## 10 auburn, white fair blue-gray
## # … with 77 more rows
# Contiene "color" como sufijo
starwars %>% select(ends_with("color"))
## # A tibble: 87 × 3
## hair_color skin_color eye_color
## <chr> <chr> <chr>
## 1 blond fair blue
## 2 <NA> gold yellow
## 3 <NA> white, blue red
## 4 none white yellow
## 5 brown light brown
## 6 brown, grey light blue
## 7 brown light blue
## 8 <NA> white, red red
## 9 black light brown
## 10 auburn, white fair blue-gray
## # … with 77 more rows