El tidyverse es una colección de paquetes diseñados para data science y que comparten un modo de trabajo similar. En este recurso aprenderemos el uso de algunos comandos del paquete dplyr, quizas uno de los más utilizados del tidyverse.

Página web del tidyverse: <https://www.tidyverse.org/>{target="Blank0"}

Figure 1: Página web del tidyverse: https://www.tidyverse.org/


Para activar los paquetes del tidyverse use el siguiente código:

library(tidyverse)  # activando paquetes del tidyverse (dplyr, ggplot2, tidyr, etc.)


Operador “pipe” (%>% ó |>)

Este operador permite pasar el objeto que esta a su izquierda como primer argumento del comando que está a su derecha, y con esto, favorece la escritura de código donde se deben usar varios comandos, uno detras de otro, para transformar un objeto.

El operador %>%|>) pasa el objeto a su izquierda como primer argumento del comando a su derecha. Es decir, el código:

f(x,y)

es equivalente a

x %>% f(y)

x |> f(y)


Paquete dplyr y comandos revisados

dplyr es un paquete que permite manipular data.frame’s o tibble’s bajo la idea de la gramática de la manipulación de datos. Bajo esta idea, el paquete provee un conjunto de verbos (comandos) que permiten solucionar los retos principales (agregar columnas, seleccionar columnas, filtrar filas, resumir, etc.) en la manipulación de datos; estos comandos se pueden ir aplicando por “capas”, o de forma secuencial, para transformar una tabla de múltiples formas. Para potenciar la idea de la gramática de la manipulación, se recomienda encadenar los comandos mediante el operador “pipe” %>% (o |>). Algunos de los comandos principales del paquete dplyr se muestran en la siguiente tabla:

Comando Descripción
mutate Adiciona nuevas variables que pueden ser o no funciones de las exitentes
select Selecciona variables por sus nombres o por posición
filter Filtrar filas de acuerdo a expresiones lógicas
summarise Reduce (o colapsa) múltiples filas a una sóla medida de resumen
arrange Ordena filas de acuerdo a variables
tally ó count Cuenta valores únicos para una o múltiples variables
group_by Agrupa por una o múltiples varibles. Al aplicar comandos tales como summarise, arrange o tally, las operaciones se realizan por grupo
ungroup Remueve el atributo de agrupado asignado por group_by
pull Extrae los valores de una columna como un vector (similar a lo que hace $)

Descargue una hoja de referencia actualizada del paquete dplyr aquí. También puede consultar la ayuda de cada comando usando el código: ?mutate, ?summarise, etc.


Datos

library(mosaicData)
data(Gestation)
?Gestation
gest <- as.data.frame(Gestation)
str(gest)
'data.frame':   1236 obs. of  23 variables:
 $ id       : num  15 20 58 61 72 100 102 129 142 148 ...
 $ pluralty : chr  "single fetus" "single fetus" "single fetus" "single fetus" ...
 $ outcome  : chr  "live birth" "live birth" "live birth" "live birth" ...
 $ date     : Date, format: "1964-11-11" "1965-02-07" ...
 $ gestation: num  284 282 279 NA 282 286 244 245 289 299 ...
 $ sex      : chr  "male" "male" "male" "male" ...
 $ wt       : num  120 113 128 123 108 136 138 132 120 143 ...
 $ parity   : num  1 2 1 2 1 4 4 2 3 3 ...
 $ race     : chr  "asian" "white" "white" "white" ...
 $ age      : num  27 33 28 36 23 25 33 23 25 30 ...
 $ ed       : chr  "College graduate" "College graduate" "HS graduate--no other schooling" "College graduate" ...
 $ ht       : num  62 64 64 69 67 62 62 65 62 66 ...
 $ wt.1     : num  100 135 115 190 125 93 178 140 125 136 ...
 $ drace    : chr  "asian" "white" "white" "white" ...
 $ dage     : num  31 38 32 43 24 28 37 23 26 34 ...
 $ ded      : chr  "College graduate" "College graduate" "8th -12th grade - did not graduate" "HS+some college" ...
 $ dht      : num  65 70 NA 68 NA 64 NA 71 70 NA ...
 $ dwt      : num  110 148 NA 197 NA 130 NA 192 180 NA ...
 $ marital  : chr  "married" "married" "married" "married" ...
 $ inc      : chr  "2500-5000" "10000-12500" "5000-7500" "20000-22500" ...
 $ smoke    : chr  "never" "never" "now" "once did, not now" ...
 $ time     : chr  "never smoked" "never smoked" "still smokes" "2 to 3 years ago" ...
 $ number   : chr  "never" "never" "1-4 per day" "20-29 per day" ...


Aplicación de comandos

Todos los comandos de tidyverse incluyendo aquellos del paquete dplyr reciben como 1er. argumento un data.frame o tibble y devuelven un data.frame o tibble, de ahí que sean facialmente encadenados por el operador “pipe” (%>% ó |>). Los argumentos siguientes dependerán del comando. Considere los siguientes ejemplos.


Comandos mutate y select

  • La variable wt.1 tiene el peso de la madre antes del embarazo en libras (pouns), crear una nueva variable wt.2 que tenga este mismo peso pero en kilogramos. Ayuda: 1 libra = 0.454 kg.

  • A partir de la variable gestation la cual está en días, crear una nueva variable gestation2 que tenga la duración de la gestación en meses. Ayuda: 1 mes = 30 días.

  • Imprima las seis primeras filas de la tabla con las cuatro variables involucradas en los cálculos anteriores para verificar los cambios.


gest %>%
  mutate(
    wt.2 = wt.1 * 0.454,             # libra a kg
    gestation2  = gestation / 30,    # dias a meses
  ) %>%
  select(id, wt.1, gestation, wt.2, gestation2) %>%
  head()
   id wt.1 gestation   wt.2 gestation2
1  15  100       284 45.400   9.466667
2  20  135       282 61.290   9.400000
3  58  115       279 52.210   9.300000
4  61  190        NA 86.260         NA
5  72  125       282 56.750   9.400000
6 100   93       286 42.222   9.533333


Comando filter

Imprima las filas de la tabla que cumplan con tener una edad de la madre menor o igual a 25 años y que sean de raza asian. De este grupo, imprima las columnas id, age, race y wt en gramos. Ordene la impresión de acuerdo a wt.

gest %>%
  filter(age <= 25 & race == "asian") %>%
  mutate(wt = wt * 28.3495) %>%
  select(id, age, race, wt) %>%
  arrange(wt)
    id age  race       wt
1 6313  25 asian 2636.503
2 8051  24 asian 2834.950
3 8484  24 asian 2948.348
4  798  25 asian 3118.445
5 6720  25 asian 3118.445
6 6027  25 asian 3345.241
7 6285  25 asian 3373.590
8 2944  24 asian 3770.483
9 6561  25 asian 3770.483


Comandos summarise y group_by

  • Calcule la cantidad de filas, la media y la desviación estándar del peso al nacimiento para las 1236 filas de la tabla.

  • Calcule la cantidad de filas, la media y la desviación estándar del peso al nacimiento para cada raza de la madre. Imprima ordenando por la media.

# Para todas las filas:
gest %>%
  summarise(
    n = n(),
    peso.nac_mean = mean(wt),
    peso.nac_sd = sd(wt)
  )
     n peso.nac_mean peso.nac_sd
1 1236      119.5769    18.23645
# Por raza:
gest %>%
  group_by(race) %>%
  summarise(
    n = n(),
    peso.nac_mean = mean(wt),
    peso.nac_sd = sd(wt)
  ) %>%
  arrange(
    peso.nac_mean
  )
# A tibble: 6 × 4
  race      n peso.nac_mean peso.nac_sd
  <chr> <int>         <dbl>       <dbl>
1 asian    44          110.        16.0
2 black   244          113.        19.1
3 <NA>     13          117.        16.7
4 mixed    25          120.        20.1
5 white   870          122.        17.7
6 mex      40          124.        14.1


Observe que comandos como mean o sd devuelven un sólo valor. Sin embargo, ciertos comandos de estadística descriptiva pueden devolver más de un valor, por ejemplo:

range( gest$wt )       # rango de los datos
[1]  55 176
quantile( gest$wt )    # quantiles, por defecto, 0,0.25,0.5,0.75,1
    0%    25%    50%    75%   100% 
 55.00 108.75 120.00 131.00 176.00 
quantile( gest$wt, prob = c(0.25, 0.75) )
   25%    75% 
108.75 131.00 
summary( gest$wt )     # resumen con varios estadisticos
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   55.0   108.8   120.0   119.6   131.0   176.0 


Tenga cuidado de aplicar alguno de estos comandos con summarise, pues a pesar de que se puede hacer, el comando summarise mantiene una sóla columna para los resultados, pero crea una fila para cada valor resultante de la función. Entonces se recomienda crear una columna adicional con un vector dando los nombres de los resultados de la función. Aquí un ejemplo:

gest %>%
  group_by(race) %>%
  summarise(
    n = n(),
    q = quantile(wt, prob = c(0.25, 0.75)),
    prob = c(25, 75)
  )
# A tibble: 12 × 4
# Groups:   race [6]
   race      n     q  prob
   <chr> <int> <dbl> <dbl>
 1 asian    44  102.    25
 2 asian    44  120     75
 3 black   244  102.    25
 4 black   244  126.    75
 5 mex      40  116.    25
 6 mex      40  133.    75
 7 mixed    25  105     25
 8 mixed    25  130     75
 9 white   870  111     25
10 white   870  133.    75
11 <NA>     13  109     25
12 <NA>     13  125     75


Ejercicios

Ejer. 1

Transforme la altura de la madre de pulgadas a centímetros en una nueva columna. Igualmente, pase el peso al nacimiento de onzas a gramos en una nueva columna. Imprima las primeras seis filas de la tabla con las columnas involucradas en los cálculos para verificar los cambios.

Código solución

gest %>%
  mutate(
    ht.cm = ht * 2.54,               # pulgadas a cm
    wt.g  = wt * 28.3495,            # onzas a gramos
  ) %>%
  select(id, ht, ht.cm, wt, wt.g) %>%
  head()


Ejer. 2

Defina tres intervalos para la variable gestation, llámelos corta, media, larga; calcule el mínimo, el máximo, la media y la desviación estándar del peso al nacimiento en gramos para cada categoría de smoke e intervalo de gestación. Intente gráficar el peso medio al nacimiento en función de las categorías de smoke partiendo por intervalos de gestación.

Código solución

# Identifique la distribucion de la gestacion
gest |>
  mutate(gestation = gestation / 30) |>
  pull(gestation) |>
  summary()

# Identificando las categorias de smoke
count(gest, smoke)

# Aqui vamos:
res <- gest |>
  filter(!is.na(smoke) & !is.na(gestation) & !is.na(wt) ) |>
  mutate(
    gestation = cut(gestation / 30, br = c(4,9,10,12), labels = c('corta', 'media', 'larga')),
    smoke     = fct_relevel(smoke, "now", after = Inf),
    wt        =  wt * 28.3495 
  )  |>
  group_by(gestation, smoke) |>
  summarise(
    n = n(),
    min = min(wt),
    max = max(wt),
    media = mean(wt),
    de    = sd(wt)
  )

res

# Grafico
ggplot(res, aes(y = smoke, x = media)) + geom_point(size = 4) +
  geom_errorbar(aes(xmin = media - de, xmax = media + de), 
                width = 0.2) +
  facet_grid(~ gestation, labeller = label_both) +
  labs(x = 'Peso al nacimiento (g)')