5  Transformar columnas

5.1 Introducción

Puesto que en el análisis de datos acostumbramos a trabajar con marcos de datos que tienen una gran cantidad de variables, nos conviene dominar las funciones que nos ayuden a hacer más fáciles las operaciones con vectores. En este apartado estudiaremos las tres funciones más importantes del paquete dplyr que operan sobre las columnas del marco de datos: select(), rename() y mutate(). Todas tienen como misión principal modificar el número, el nombre o el orden de las columnas de un marco de datos dejando el número o el orden de las filas inalterado. Las tres funciones que estudiaremos son las siguientes:

  • select(): selecciona una o más columnas del marco de datos.
  • rename(): renombra una o más columnas del marco de datos.
  • mutate(): modifica los valores de una o más columnas del marco de datos.

Estas funciones son especialmente útiles en marcos de datos de grandes dimensiones, que almacenan una gran cantidad de variables. Es por eso que en este apartado trabajaremos con el marco de datos nuts, una versión mucho más amplia —tiene 368 observaciones y 74 variables— que el marco de datos nuts_mini que hemos trabajado en el apartado anterior.

Ejercicio 5.1 (Prepara los datos) Asegúrate que tienes cargado en el Global Environment el marco de datos nuts. Haz una exploración rápida de los datos antes de continuar:

  • Examina qué variables tenemos con glimpse().
  • Identifica la variable o variables que contienen la unidad de observación y examínalas con unique().
  • El marco de datos contiene variables de la European Social Survey (ESS) (ESS, 2018) y el European Quality of Government Institute (EQI) (Charron et al., 2020; Charron & Lapuente, 2018). Consulta los libros de códigos para identificar el significado de estas variables. (Las primeras variables son del paquete Eurostat, de la variable d3 a la q32 son de ESS, y de ppltrst al final son de EQI.)

5.2 Select

La función select() sirve para reducir el número de columnas. La manera más sencilla de utilizar la función es indicar en cada argumento el nombre de las columnas que queremos conservar.

La manera más sencilla de utilizar select() es indicando el nombre de las columnas que queremos conservar. El código siguiente nos devuelve un marco de datos que contendrá solo las variables ccode, name, innov y density y eliminará todas las otras.

nuts |> 
  select(ccode, name, innov, density)
# A tibble: 368 × 4
   ccode name                         innov density
   <chr> <chr>                        <dbl>   <dbl>
 1 AT    Burgenland                    125.    79.7
 2 AT    Niederösterreich              125.    88.2
 3 AT    Wien                          125.  4755. 
 4 AT    Kärnten                       122.    59.9
 5 AT    Steiermark                    122.    76.2
 6 AT    Oberösterreich                121.   125. 
 7 AT    Salzburg                      121.    78.1
 8 AT    Tirol                         121.    59.8
 9 AT    Vorarlberg                    121.   154  
10 BE    Région De Bruxelles-Capitale  136.  7422. 
# ℹ 358 more rows

R respetará la orden en el que introducimos el nombre de las columnas vectores. En este ejemplo pedimos las mismas variables que en la pestaña anterior (Selección) pero en un orden diferente.

nuts |> 
  select(name, ccode, density, innov)
# A tibble: 368 × 4
   name                         ccode density innov
   <chr>                        <chr>   <dbl> <dbl>
 1 Burgenland                   AT       79.7  125.
 2 Niederösterreich             AT       88.2  125.
 3 Wien                         AT     4755.   125.
 4 Kärnten                      AT       59.9  122.
 5 Steiermark                   AT       76.2  122.
 6 Oberösterreich               AT      125.   121.
 7 Salzburg                     AT       78.1  121.
 8 Tirol                        AT       59.8  121.
 9 Vorarlberg                   AT      154    121.
10 Région De Bruxelles-Capitale BE     7422.   136.
# ℹ 358 more rows

También podemos renombrar una columna en el mismo momento que la seleccionamos. En el código siguiente hemos renombrado el nombre del vector ccode. Dentro del argumento indicaremos primero el nombre nuevo que tendrá el vector, seguido de = y el nombre antiguo del vector.

nuts |> 
  select(country = ccode, name, innov)
# A tibble: 368 × 3
   country name                         innov
   <chr>   <chr>                        <dbl>
 1 AT      Burgenland                    125.
 2 AT      Niederösterreich              125.
 3 AT      Wien                          125.
 4 AT      Kärnten                       122.
 5 AT      Steiermark                    122.
 6 AT      Oberösterreich                121.
 7 AT      Salzburg                      121.
 8 AT      Tirol                         121.
 9 AT      Vorarlberg                    121.
10 BE      Région De Bruxelles-Capitale  136.
# ℹ 358 more rows

A veces, puede ser que queramos simplemente eliminar algunas columnas. En este caso, indicaremos el nombre de la columna o las columnas que queremos eliminar con el símbolo negativo (-) delante. Conservaremos todo el resto de columnas.

nuts |> 
  select(-level, -geo)
# A tibble: 368 × 72
   ccode country nuts  name    gdpcap_nuts gdpcap_ctr    pop density  land   lon
   <chr> <chr>   <chr> <chr>         <dbl>      <dbl>  <dbl>   <dbl> <dbl> <dbl>
 1 AT    Austria AT11  Burgen…       29800      42000 2.92e5    79.7  3962 16.5 
 2 AT    Austria AT12  Nieder…       34900      42000 1.67e6    88.2 19186 15.8 
 3 AT    Austria AT13  Wien          49500      42000 1.87e6  4755.    415 16.4 
 4 AT    Austria AT21  Kärnten       35500      42000 5.61e5    59.9  9538 13.9 
 5 AT    Austria AT22  Steier…       38400      42000 1.24e6    76.2 16401 15.0 
 6 AT    Austria AT31  Oberös…       42900      42000 1.47e6   125.  11980 14.0 
 7 AT    Austria AT32  Salzbu…       50200      42000 5.49e5    78.1  7156 13.1 
 8 AT    Austria AT33  Tirol         44600      42000 7.46e5    59.8 12640 11.5 
 9 AT    Austria AT34  Vorarl…       46000      42000 3.89e5   154    2601  9.89
10 BE    Belgium BE1   Région…       68400      39100 1.20e6  7422.    161  4.37
# ℹ 358 more rows
# ℹ 62 more variables: lat <dbl>, capital <chr>, lon_cap <dbl>, lat_cap <dbl>,
#   distance <dbl>, innov <dbl>, d3 <dbl>, d6 <dbl>, q1 <dbl>, q2 <dbl>,
#   q3 <dbl>, q4 <dbl>, q5 <dbl>, q6 <dbl>, q7 <dbl>, q8 <dbl>, q9 <dbl>,
#   q10 <dbl>, q11 <dbl>, q12 <dbl>, q13 <dbl>, q14 <dbl>, q15 <dbl>,
#   q16 <dbl>, q17_1 <dbl>, q17_2 <dbl>, q18_1 <dbl>, q18_2 <dbl>, q18_3 <dbl>,
#   q18_4 <dbl>, q19_1 <dbl>, q19_2 <dbl>, q19_3 <dbl>, q19_4 <dbl>, …

Tenemos varios atajos que nos permiten no tener que introducir el nombre de los vectores que queremos conservar. Con los dos puntos (:), indicamos la selección desde una variable hasta otra. Por ejemplo, si queremos conservar desde el vector geo hasta el vector pop, lo tendremos que indicar como geo:pop. Además, en otro argumento podemos indicar el nombre de otros vectores que también queremos conservar.

nuts |> 
  select(geo:pop, land, capital)
# A tibble: 368 × 6
   geo   gdpcap_nuts gdpcap_ctr     pop  land capital 
   <chr>       <dbl>      <dbl>   <dbl> <dbl> <chr>   
 1 AT11        29800      42000  291942  3962 Vienna  
 2 AT12        34900      42000 1665753 19186 Vienna  
 3 AT13        49500      42000 1867582   415 Vienna  
 4 AT21        35500      42000  561077  9538 Vienna  
 5 AT22        38400      42000 1237298 16401 Vienna  
 6 AT31        42900      42000 1465045 11980 Vienna  
 7 AT32        50200      42000  549263  7156 Vienna  
 8 AT33        44600      42000  746153 12640 Vienna  
 9 AT34        46000      42000  388752  2601 Vienna  
10 BE1         68400      39100 1199095   161 Brussels
# ℹ 358 more rows

En select() podemos incluir algunas funciones específicas, que resumimos en la tabla 5.1.

Tabla 5.1: Funciones para seleccionar variables
Función Acción
everything() Selecciona todas las columnas.
starts_with() Selecciona las columnas que empiecen con unos caracteres determinados.
ends_with() Selecciona las columnas que acaben con unos caracteres determinados.
contains() Selecciona las columnas que contengan unos caracteres determinados.
last_col() Selecciona la última columna.

Estas funciones nos ayudarán a simplificar la selección de las variables que queremos retener. A continuación vemos algunos ejemplos.

Queremos cambiar de orden algunas columnas situándolas al principio, pero mantener el resto. Podemos utilizar everything().

nuts |> 
  select(name, geo, everything())
# A tibble: 368 × 74
   name    geo   ccode country nuts  level gdpcap_nuts gdpcap_ctr    pop density
   <chr>   <chr> <chr> <chr>   <chr> <int>       <dbl>      <dbl>  <dbl>   <dbl>
 1 Burgen… AT11  AT    Austria AT11      2       29800      42000 2.92e5    79.7
 2 Nieder… AT12  AT    Austria AT12      2       34900      42000 1.67e6    88.2
 3 Wien    AT13  AT    Austria AT13      2       49500      42000 1.87e6  4755. 
 4 Kärnten AT21  AT    Austria AT21      2       35500      42000 5.61e5    59.9
 5 Steier… AT22  AT    Austria AT22      2       38400      42000 1.24e6    76.2
 6 Oberös… AT31  AT    Austria AT31      2       42900      42000 1.47e6   125. 
 7 Salzbu… AT32  AT    Austria AT32      2       50200      42000 5.49e5    78.1
 8 Tirol   AT33  AT    Austria AT33      2       44600      42000 7.46e5    59.8
 9 Vorarl… AT34  AT    Austria AT34      2       46000      42000 3.89e5   154  
10 Région… BE1   BE    Belgium BE1       1       68400      39100 1.20e6  7422. 
# ℹ 358 more rows
# ℹ 64 more variables: land <dbl>, lon <dbl>, lat <dbl>, capital <chr>,
#   lon_cap <dbl>, lat_cap <dbl>, distance <dbl>, innov <dbl>, d3 <dbl>,
#   d6 <dbl>, q1 <dbl>, q2 <dbl>, q3 <dbl>, q4 <dbl>, q5 <dbl>, q6 <dbl>,
#   q7 <dbl>, q8 <dbl>, q9 <dbl>, q10 <dbl>, q11 <dbl>, q12 <dbl>, q13 <dbl>,
#   q14 <dbl>, q15 <dbl>, q16 <dbl>, q17_1 <dbl>, q17_2 <dbl>, q18_1 <dbl>,
#   q18_2 <dbl>, q18_3 <dbl>, q18_4 <dbl>, q19_1 <dbl>, q19_2 <dbl>, …

La función starts_with() selecciona las columnas que empiezan con unos caracteres determinados. Por ejemplo, sabemos que las variables de la ESS empiezan por la letra q. Entonces, si queremos trabajar únicamente con estos datos, podemos seleccionar primero algunas variables que correspondan con la unidad de observación e indicar después que queremos conservar solo aquellas variables que empiecen por q.

nuts |> 
  select(ccode, nuts, starts_with("q"))
# A tibble: 368 × 42
   ccode nuts     q1    q2    q3    q4    q5    q6    q7    q8    q9   q10   q11
   <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1 AT    AT11   1.69  1.39  1.78  6.91  7.22  7.23  4.74  5.31  4.35  1.99  2.10
 2 AT    AT12   1.73  1.36  1.77  7.04  7.37  7.26  4.62  5.43  4.20  1.94  2.13
 3 AT    AT13   1.69  1.30  1.77  6.65  7.55  7.08  4.89  5.49  4.37  2.13  2.24
 4 AT    AT21   1.69  1.38  1.77  6.88  7.47  7.25  4.76  5.23  4.27  2.08  2.14
 5 AT    AT22   1.67  1.33  1.77  7.01  7.35  7.12  4.79  5.34  4.19  1.92  2.05
 6 AT    AT31   1.68  1.33  1.75  7     7.27  7.13  4.71  5.35  4.06  1.99  2.12
 7 AT    AT32   1.63  1.34  1.75  7.04  7.66  7.27  4.76  5.44  4.25  1.94  2.09
 8 AT    AT33   1.67  1.33  1.73  7.25  7.83  7.25  4.68  5.21  4.21  1.99  2.12
 9 AT    AT34   1.66  1.38  1.76  7.22  7.86  7.48  4.99  5.64  4.29  2     2.13
10 BE    BE1    1.56  1.38  1.73  6.58  7.39  6.63  5.78  5.91  5.49  2.32  2.18
# ℹ 358 more rows
# ℹ 29 more variables: q12 <dbl>, q13 <dbl>, q14 <dbl>, q15 <dbl>, q16 <dbl>,
#   q17_1 <dbl>, q17_2 <dbl>, q18_1 <dbl>, q18_2 <dbl>, q18_3 <dbl>,
#   q18_4 <dbl>, q19_1 <dbl>, q19_2 <dbl>, q19_3 <dbl>, q19_4 <dbl>, q20 <dbl>,
#   q22_1 <dbl>, q22_2 <dbl>, q23_1 <dbl>, q23_2 <dbl>, q23_3 <dbl>, q25 <dbl>,
#   q26 <dbl>, q27 <dbl>, q28 <dbl>, q30 <dbl>, q31_1 <dbl>, q31_2 <dbl>,
#   q32 <dbl>

Las funciones ends_with() y contains() operan con la misma lógica que starts_with().

La función last_col() se usa a menudo en combinación con los dos puntos (:) para indicar que queremos seleccionar un grupo de variables que se encuentra al final del marco de datos. En este ejemplo hemos seleccionado las variables de EQI, que son desde ppltrst hasta la última columna de datos.

nuts |> 
  select(ccode, nuts, ppltrst:last_col())
# A tibble: 368 × 16
   ccode nuts  ppltrst sgnptit lrscale stfgov freehms imueclt atchctr atcherp
   <chr> <chr>   <dbl>   <dbl>   <dbl>  <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
 1 AT    AT11     5.86    1.89    4.97   4.5     1.97    4.09    8.66    5.21
 2 AT    AT12     5.74    1.74    5.28   4.60    2.06    4.28    7.98    5.22
 3 AT    AT13     5.10    1.64    4.36   4.57    2.02    5.40    7.55    6.36
 4 AT    AT21     4.92    1.80    5.09   3.27    2       3.57    8.41    5.27
 5 AT    AT22     4.7     1.87    4.94   3.96    2.06    4.11    8.05    5.82
 6 AT    AT31     6.08    1.82    5.59   5.01    1.91    4.44    7.98    5.78
 7 AT    AT32     5.57    1.76    4.75   4.40    1.80    4.80    6.99    5.55
 8 AT    AT33     5.06    1.73    5.03   4.62    1.86    4.96    8.30    5.79
 9 AT    AT34     4.77    1.73    4.97   3.66    2.45    3.89    7.94    5.52
10 BE    BE1      4.37    1.80    4.35   5.03    2.27    7.01    7.02    6.16
# ℹ 358 more rows
# ℹ 6 more variables: dscrgrp <dbl>, dscrntn <dbl>, dscrlng <dbl>,
#   dscretn <dbl>, blgetmg <dbl>, gvrfgap <dbl>

Ejercicio 5.2 (Selecciona cuatro variables de interés) Con la función select(), construye un marco de datos que esté formado por las dos (o tres) columnas de la unidad de observación y por cuatro variables que te parezcan interesantes. Selecciona dos de cada base de datos: dos de Eurostat, dos de ESS y dos de EQI.

5.3 Rename

La función rename() renombra el nombre de las columnas que indicamos conservando todas las otras columnas. Su estructura es muy sencilla: dentro de la función indicaremos primero el nombre nuevo que tendrá el vector en cuestión, seguido del símbolo = y del nombre antiguo del vector.

df |> 
  rename(nombre_nuevo = nombre_antiguo)

A diferencia de select(), la función rename() no suprime ninguna columna, sino que solo cambia los nombres indicados. Se pueden añadir tantos argumentos como nombres de columnas se quieran cambiar. Veamos un ejemplo:

nuts |> 
  rename(country_name = country, 
         nuts_name = name)
# A tibble: 368 × 74
   ccode country_name nuts  level nuts_name  geo   gdpcap_nuts gdpcap_ctr    pop
   <chr> <chr>        <chr> <int> <chr>      <chr>       <dbl>      <dbl>  <dbl>
 1 AT    Austria      AT11      2 Burgenland AT11        29800      42000 2.92e5
 2 AT    Austria      AT12      2 Niederöst… AT12        34900      42000 1.67e6
 3 AT    Austria      AT13      2 Wien       AT13        49500      42000 1.87e6
 4 AT    Austria      AT21      2 Kärnten    AT21        35500      42000 5.61e5
 5 AT    Austria      AT22      2 Steiermark AT22        38400      42000 1.24e6
 6 AT    Austria      AT31      2 Oberöster… AT31        42900      42000 1.47e6
 7 AT    Austria      AT32      2 Salzburg   AT32        50200      42000 5.49e5
 8 AT    Austria      AT33      2 Tirol      AT33        44600      42000 7.46e5
 9 AT    Austria      AT34      2 Vorarlberg AT34        46000      42000 3.89e5
10 BE    Belgium      BE1       1 Région De… BE1         68400      39100 1.20e6
# ℹ 358 more rows
# ℹ 65 more variables: density <dbl>, land <dbl>, lon <dbl>, lat <dbl>,
#   capital <chr>, lon_cap <dbl>, lat_cap <dbl>, distance <dbl>, innov <dbl>,
#   d3 <dbl>, d6 <dbl>, q1 <dbl>, q2 <dbl>, q3 <dbl>, q4 <dbl>, q5 <dbl>,
#   q6 <dbl>, q7 <dbl>, q8 <dbl>, q9 <dbl>, q10 <dbl>, q11 <dbl>, q12 <dbl>,
#   q13 <dbl>, q14 <dbl>, q15 <dbl>, q16 <dbl>, q17_1 <dbl>, q17_2 <dbl>,
#   q18_1 <dbl>, q18_2 <dbl>, q18_3 <dbl>, q18_4 <dbl>, q19_1 <dbl>, …
Recapitulación y consejos

Con las funciones que hemos visto, ya podemos ver cómo quedaría una transformación del marco de datos con diversas variables implicadas. Lo más importante de todo es tener clara la pregunta que nos queremos hacer sobre los datos y después pensar cómo iremos desplegando el código que necesitamos para llegar a la respuesta. Por ejemplo:

En Portugal, ¿cuáles son las regiones que toleran más, de media, la homosexualidad y la inmigración?

  • Filtraremos los datos por Portugal.
  • Seleccionaremos las tres variables que nos interesan: el nombre de la unidad de observación (name), tolerancia de la homosexualidad (freehms) y la inmigración (imueclt).
  • Estableceremos algún criterio para ordenar los datos de más tolerantes a menos tolerantes. En este caso, ordenaremos por imueclt en orden descendente.
nuts |> 
  filter(country == "Portugal") |> 
  select(name, freehms, imueclt) |> 
  arrange(desc(imueclt))
# A tibble: 7 × 3
  name                         freehms imueclt
  <chr>                          <dbl>   <dbl>
1 Área Metropolitana De Lisboa    1.74    6.48
2 Alentejo                        1.97    6.08
3 Centro (Pt)                     1.87    6.02
4 Norte                           1.91    6.02
5 Algarve                         2.02    5.9 
6 Região Autónoma Dos Açores     NA      NA   
7 Região Autónoma Da Madeira     NA      NA   

Ejercicio 5.3 (Elimina los datos perdidos) En el apartado Recapitulación y consejos el marco de datos que hemos transformado contiene dos observaciones con valores perdidos. ¿Qué código utilizarías para eliminar estas filas?

Hay muchas maneras de eliminar las filas que contienen datos perdidos. Una opción es introducir una última línea de código que excluya los NA:

nuts |> 
  ... |>  
  filter(!is.na(imueclt))

5.4 Mutate

La función mutate() permite transformar los valores de una variable. La estructura interna de la función consta de los elementos siguientes:

  1. Indicamos el nombre del vector de destino donde guardaremos la operación.
  2. Ubicamos el símbolo igual (=).
  3. Especificamos la operación en cuestión.
df |> 
  mutate(vector_destino = operación)

Lo más importante que se debe tener en cuenta con mutate() es el vector de destino, puesto que, según como lo indicamos, sobrescribiremos los datos en un vector ya existente o bien crearemos un vector nuevo:

  1. Si el nombre del vector de destino donde guardaremos la operación ya existe en el marco de datos, R sobrescribirá los datos en el vector especificado. En el ejemplo de la derecha, en el marco de datos df hemos multiplicado por 100 los valores del vector vec. Como el vector de destino es el mismo vector, el resultado de la operación se sobrescribirá en vec.
df |> 
  mutate(vec = vec * 100)
  1. Si, en cambio, el nombre del vector donde guardaremos la operación no existe en el marco de datos, R creará un nuevo vector con el nombre indicado que contendrá el resultado de la operación. En el ejemplo de la derecha, en el marco de datos df hemos multiplicado por 100 los valores del vector vec. Como en este caso guardamos el resultado en vec_nuevo, un vector que todavía no existe en el marco de datos, nos creará un nuevo vector con este nombre que contendrá el resultado de la operación.
df |> 
  mutate(vec_nuevo = vec * 100)

Como veremos a continuación, dentro de mutate() podemos hacer muchas operaciones que hasta ahora hemos aprendido en capítulos anteriores. En este primer bloque de ejemplos, utilizamos operaciones básicas como sumar, restar, multiplicar o dividir valores de varias variables. Al tratarse de operaciones con vectores numéricos, hay que recordar que, en función de la longitud de los vectores, podemos hacer dos tipos de operaciones (ved el cuadro de la derecha).

Vectores numéricos

Según la longitud de los vectores, podemos hacer dos tipos de operaciones:

  • Entre un vector y un número, realizamos la operación de todos los valores del vector por el número en cuestión.
c(30, 40) / 2
[1] 15 20
  • Entre vectores de igual longitud, hacemos la operación entre los valores que tienen la misma posición en el vector.
c(30, 40) / c(2, 1)
[1] 15 40

Para facilitar el seguimiento de los ejemplos, en el código reduciremos el número de variables con select().

Para hacer más fácil la lectura de los datos de población, queremos que la unidad sea el millón, de forma que, en lugar de ver una cifra de 1.000.000, la vemos 1. Para eso dividiremos el vector de la variable pop entre un millón. Como el resultado lo guardamos en pop, R nos sobrescribirá el resultado en la misma columna.

nuts |> 
  select(name, pop) |> 
  mutate(pop = pop / 1000000)
# A tibble: 368 × 2
   name                           pop
   <chr>                        <dbl>
 1 Burgenland                   0.292
 2 Niederösterreich             1.67 
 3 Wien                         1.87 
 4 Kärnten                      0.561
 5 Steiermark                   1.24 
 6 Oberösterreich               1.47 
 7 Salzburg                     0.549
 8 Tirol                        0.746
 9 Vorarlberg                   0.389
10 Région De Bruxelles-Capitale 1.20 
# ℹ 358 more rows

¿Cuál es el PIB total de cada región? Esta información la podemos obtener si multiplicamos el PIB per cápita de la región (gdpcap_nuts) por su población (pop). En este caso, en el código indicaremos el nombre de una columna nueva que todavía no existe en el marco de datos: gdp_nuts. Como esta variable no existe, R mantendrá el nombre de las columnas originales con las que hemos hecho la operación (gdpcap_nuts, pop) y guardará el resultado en una columna nueva llamada gdp_nuts.

nuts |> 
  select(name, gdpcap_nuts, pop) |> 
  mutate(gdp_nuts = gdpcap_nuts * pop)
# A tibble: 368 × 4
   name                         gdpcap_nuts     pop    gdp_nuts
   <chr>                              <dbl>   <dbl>       <dbl>
 1 Burgenland                         29800  291942  8699871600
 2 Niederösterreich                   34900 1665753 58134779700
 3 Wien                               49500 1867582 92445309000
 4 Kärnten                            35500  561077 19918233500
 5 Steiermark                         38400 1237298 47512243200
 6 Oberösterreich                     42900 1465045 62850430500
 7 Salzburg                           50200  549263 27573002600
 8 Tirol                              44600  746153 33278423800
 9 Vorarlberg                         46000  388752 17882592000
10 Région De Bruxelles-Capitale       68400 1199095 82018098000
# ℹ 358 more rows

También podemos combinar varias operaciones dentro de mutate() siempre que vayan separadas con una coma. En el código siguiente hemos hecho el cálculo siguiente:

  1. El PIB total de cada región (ved la pestaña Nuevo Vector).
  2. Después de una coma, en una línea nueva hacemos una nueva operación en la que calculamos la distancia de cada región respecto a la capital del país y guardamos el resultado a dist.
  3. Después de otra coma, dividimos por un millón los valores de la variable pop y sobrescribimos el resultado en la misma variable. Para acabar, en una nueva pipe, seleccionamos solo las variables que hemos creado o modificado para ver mejor el resultado de la transformación.
nuts |> 
  mutate(gdp_nuts = gdpcap_nuts * pop,
         dist = sqrt(abs(lon_cap - lon) * abs(lat_cap - lat)),
         pop = pop / 1000000) |> 
    select(name, gdpcap_nuts, dist, pop)
# A tibble: 368 × 4
   name                         gdpcap_nuts    dist   pop
   <chr>                              <dbl>   <dbl> <dbl>
 1 Burgenland                         29800 0.317   0.292
 2 Niederösterreich                   34900 0.210   1.67 
 3 Wien                               49500 0.00964 1.87 
 4 Kärnten                            35500 1.87    0.561
 5 Steiermark                         38400 1.12    1.24 
 6 Oberösterreich                     42900 0.390   1.47 
 7 Salzburg                           50200 1.63    0.549
 8 Tirol                              44600 2.21    0.746
 9 Vorarlberg                         46000 2.49    0.389
10 Région De Bruxelles-Capitale       68400 0.0107  1.20 
# ℹ 358 more rows

Tened en cuenta que el orden en el que establecemos las diferentes operaciones dentro de mutate() puede determinar la tabla resultante. Si en la primera operación hacemos los cálculos para modificar pop, el nuevo resultado de pop modificará los valores de la operación para calcular los valores de gdp_nuts.

Aparte de operaciones entre vectores, dentro de mutate() también podemos utilizar funciones. Dos de las más frecuentes son if_else() y case_when(), que nos son extremadamente útiles para transformar variables numéricas en variables categóricas. A continuación vemos algunos ejemplos de cómo utilizarlas.

¿Qué regiones NUTS son urbanas? Con if_else(), hemos creado la variable dummy urban que toma el valor 1 si la región en cuestión tiene más de un millón de habitantes o bien una densidad superior al millar de habitantes por kilómetro cuadrado.

nuts |> 
  mutate(urban = if_else(pop > 1000000 | density > 1000, 1, 0)) |> 
    select(name, pop, density, urban)
# A tibble: 368 × 4
   name                             pop density urban
   <chr>                          <dbl>   <dbl> <dbl>
 1 Burgenland                    291942    79.7     0
 2 Niederösterreich             1665753    88.2     1
 3 Wien                         1867582  4755.      1
 4 Kärnten                       561077    59.9     0
 5 Steiermark                   1237298    76.2     1
 6 Oberösterreich               1465045   125.      1
 7 Salzburg                      549263    78.1     0
 8 Tirol                         746153    59.8     0
 9 Vorarlberg                    388752   154       0
10 Région De Bruxelles-Capitale 1199095  7422.      1
# ℹ 358 more rows

¿Qué regiones tienen la población más de izquierdas, cuáles más de centro y cuáles más de derechas? Con case_when(), hemos creado una variable categórica que adopta el valor “Right” si la media del posicionamiento de la población en el eje izquierda-derecha es superior a 5.5, “Center” si es entre 4.5 y 5.5 y “Left” si es inferior a 4.5.

nuts |> 
  mutate(lr = case_when(lrscale > 5.5 ~ "Right",
                        lrscale > 4.5 ~ "Center",
                        lrscale > 0 ~ "Left")) |>
    select(name, lr, lrscale)
# A tibble: 368 × 3
   name                         lr     lrscale
   <chr>                        <chr>    <dbl>
 1 Burgenland                   Center    4.97
 2 Niederösterreich             Center    5.28
 3 Wien                         Left      4.36
 4 Kärnten                      Center    5.09
 5 Steiermark                   Center    4.94
 6 Oberösterreich               Right     5.59
 7 Salzburg                     Center    4.75
 8 Tirol                        Center    5.03
 9 Vorarlberg                   Center    4.97
10 Région De Bruxelles-Capitale Left      4.35
# ℹ 358 more rows

¿Qué porcentaje sobre el territorio total ocupa cada región? La fórmula x / sum(x) es muy útil para calcular proporciones con nuestros datos. Después, hemos multiplicado el resultado por 100 para obtener el porcentaje.

nuts |> 
  mutate(land_percentage = land / sum(land, na.rm = T) * 100) |> 
    select(name, land, land_percentage)
# A tibble: 368 × 3
   name                          land land_percentage
   <chr>                        <dbl>           <dbl>
 1 Burgenland                    3962         0.113  
 2 Niederösterreich             19186         0.547  
 3 Wien                           415         0.0118 
 4 Kärnten                       9538         0.272  
 5 Steiermark                   16401         0.467  
 6 Oberösterreich               11980         0.341  
 7 Salzburg                      7156         0.204  
 8 Tirol                        12640         0.360  
 9 Vorarlberg                    2601         0.0741 
10 Région De Bruxelles-Capitale   161         0.00459
# ℹ 358 more rows
La función transmute()

La función transmute() es de la familia de mutate() o select() y, de hecho, combina algunas propiedades de estas dos funciones. A diferencia de select(), permite hacer operaciones dentro de la función. Y, a diferencia de mutate(), permite seleccionar variables. Lo más habitual es, primero, escribir el código con select() y mutate() y, después, percatarnos de que podemos reducir el código y hacerlo más entendedor si sustituimos estas dos funciones por transmute(). Por ejemplo, fijaos cómo simplificamos todos los códigos que acabamos de usar en la caja anterior:

nuts |> 
  transmute(name, 
            lr = case_when(lrscale > 5.5 ~ "Right",
                        lrscale > 4.5 ~ "Center",
                        lrscale > 0 ~ "Left"),
            land_percentage = land / sum(land, na.rm = T) * 100,
            urban = if_else(pop > 1000000 | density > 1000, 1, 0)) 
# A tibble: 368 × 4
   name                         lr     land_percentage urban
   <chr>                        <chr>            <dbl> <dbl>
 1 Burgenland                   Center         0.113       0
 2 Niederösterreich             Center         0.547       1
 3 Wien                         Left           0.0118      1
 4 Kärnten                      Center         0.272       0
 5 Steiermark                   Center         0.467       1
 6 Oberösterreich               Right          0.341       1
 7 Salzburg                     Center         0.204       0
 8 Tirol                        Center         0.360       0
 9 Vorarlberg                   Center         0.0741      0
10 Région De Bruxelles-Capitale Left           0.00459     1
# ℹ 358 more rows