Explorar datos

En estos ejemplos, vamos a utilizar el paquete {palmerpenguins}. Si no lo has instalado ahora, por favor hazlo antes de continuar, y carga la librería.

#install.packages("palmerpenguins")
library(palmerpenguins)

Al cargar la librería, automáticamente tendremos disponible una nueva tabla de datos, llamada penguins. Vamos a explorar la tabla para ver qué aspecto tiene:

head(penguins)

Visualización de datos

Uno de los paquetes más usados para la visualización de datos en Ciencias de la Salud es {ggplot2}. Este paquete viene incluído en {tidyverse} (que se carga al principio de este documento, así que no tenéis que cargarlo manualmente), pero también podemos cargarlo por separado, sin añadir todas las funciones de tidyverse:

library(ggplot2)

En la página oficial de ggplot2 podéis encontrar mucha información y muchos ejemplos de diferentes gráficos. Es siempre buen lugar para empezar si queréis familiarizaros con el paquete, o estáis buscando código para un tipo de gráfico concreto.

Nuestro primer gráfico en R

Si llamamos a la función ggplot ejecutando ggplot(), veremos que nos aparece un gráfico en blanco.

Podemos considerar que esto es como nuestro “lienzo”. Si buscamos ayuda sobre la función, veremos que el primer parámetro que tenemos que introducir es data. Al introducirlo, ¿qué obtenemos?:

ggplot(data = penguins)

  • Crea un gráfico vacío que está preparado para mostrar los datos de los pingüinos

  • Como aún no le hemos dicho cómo visualizarlos, por ahora está vacío.

  • Puedes pensar en él como un lienzo vacío sobre el que pintarás las capas restantes de tu gráfico.

Añadiendo capas a nuestro gráfico

A continuación, debemos indicar a ggplot() cómo se representará visualmente la información de nuestros datos.

  • El argumento mapping define cómo se asignan las variables de nuestros datos a las propiedades visuales (estéticas) del gráfico.

  • El mapping siempre se define en la función aes(), y los argumentos x e y de aes() especifican qué variables mapear a los ejes x e y.

Vamos a intentar asignar al eje x la variable flipper_length_mm de nuestros datos, y la variable body_mass_g al eje y:

ggplot(data = penguins,
       mapping = aes(x = flipper_length_mm,
                     y = body_mass_g)
       )

💡¿Qué pasa si quitas el argumento data?

Nuestro lienzo vacío tiene ahora más estructura: está claro dónde se mostrarán las longitudes de las aletas (en el eje x) y dónde se mostrarán las masas corporales (en el eje y).

Pero los pingüinos aún no aparecen en el gráfico.

Esto se debe a que todavía no le hemos dicho a ggplot cómo representar las observaciones. Para ello deberemos definir un “geom”

Añadiendo un geom

Un “geom” es el objeto geométrico que utiliza un gráfico para representar los datos.

Los diferentes geoms se acceden mediante funciones que empiezan por geom_. Por ejemplo:

  • Los gráficos de barras utilizan geom de barras (geom_bar()),

  • Los gráficos de líneas utilizan geom de líneas (geom_line())

  • Los boxplots utilizan geom de boxplots (geom_boxplot())

  • Los scatterplots utilizan geom de puntos (geom_point())

💡¿Qué geom deberíamos utilizar aquí? Si no lo tienes claro, de nuevo, puedes visitar la página oficial de ggplot2

ggplot(data = penguins,
       mapping = aes(x = flipper_length_mm,
                     y = body_mass_g)) +
  geom_point()
## Warning: Removed 2 rows containing missing values (`geom_point()`).

💡 ¿Cómo podemos pintar los colores del scatterplot en función de la especie de pingüino?

Pista: comprueba los diferentes argumentos que puede tomar la función aes()

ggplot(data = penguins,
       mapping = aes(x = flipper_length_mm,
                     y = body_mass_g,
                     color = species)) +
  geom_point()
## Warning: Removed 2 rows containing missing values (`geom_point()`).

💡Si quisiéramos añadir una línea que indicase la relación entre los puntos, ¿sería un aes o un geom?

Puedes probar, por ejemplo, con geom_line(). ¿Es eso lo que queremos? ¿Y si usamos ‘geom_smooth()’?

ggplot(data = penguins,
       mapping = aes(x = flipper_length_mm,
                     y = body_mass_g,
                     color = species)) +
  geom_point() +
  geom_smooth(method="lm")
## `geom_smooth()` using formula = 'y ~ x'
## Warning: Removed 2 rows containing non-finite values (`stat_smooth()`).
## Warning: Removed 2 rows containing missing values (`geom_point()`).

Cada geom puede tener su mapping

En realidad, en este caso, sería más útil tener una línea de regresión para todos los casos, no una para cada especie.

Aquí, es importante que entendamos que cada geom puede tener su mapping. En este caso, el mapping es casi idéntico para geom_point y para geom_smooth. La única diferencia es que en geom_point necesitamos indicar también qué variable tiene asignada el color.

Por lo tanto, una opción puede ser establecer los mappings compartidos al principio cuando llamamos a ggplot(), y luego añadir el mapping que necesitamos extra cuando llamamos a `geom_point``

ggplot(data = penguins,
       mapping = aes(x = flipper_length_mm,
                     y = body_mass_g)) +
  geom_point(mapping = aes(color = species)) +
  geom_smooth(method = "lm")
## `geom_smooth()` using formula = 'y ~ x'
## Warning: Removed 2 rows containing non-finite values (`stat_smooth()`).
## Warning: Removed 2 rows containing missing values (`geom_point()`).

Editando el texto de ejes, títulos, leyenda…

Una función muy útil dentro de ggplot es labs(). Busca la ayuda de esta función para ver qué parámetros tiene.

Intenta usar esos parámetros para editar el gráfico y que contenga el siguiente texto:

  • Título: Masa corporal y longitud del pico

  • Eje x: longitud del pico (mm)

  • Eje y: Masa corporal (g)

ggplot(data = penguins,
       mapping = aes(x = flipper_length_mm,
                     y = body_mass_g)) +
  geom_point(aes(color = species)) +
  geom_smooth(method = "lm") +
  labs(
    title = "Masa corporal y longitud del pico",
    x = "longitud del pico (mm)",
    y = "masa corporal (g)",
    color = "especie"
  ) +
  theme_classic(base_size = 21)
## `geom_smooth()` using formula = 'y ~ x'
## Warning: Removed 2 rows containing non-finite values (`stat_smooth()`).
## Warning: Removed 2 rows containing missing values (`geom_point()`).

Visualizar más de un gráfico a la vez

Existen diferentes formas de visualizar más de un gráfico a la vez. Uno de los paquetes más versátiles y a la vez intuitivos es {patchwork}. Antes de empezar, asegúrate de que tienes este paquete instalado.

#install.packages("patchwork")
library(patchwork)

Ahora, antes de nada, vamos a crear dos gráficos diferentes:

plot_sex <- ggplot(data = penguins,
                   mapping = aes(x = species,
                                 color = sex,
                                 fill = sex)) +
  geom_bar(position="dodge") 

plot_island <- ggplot(data = penguins,
                   mapping = aes(x = species,
                                 color = island,
                                 fill = island)) +
  geom_bar(position="dodge") 

Ahora vamos a usar {patchwork} para visualizarlos a la vez.

Podemos poner un gráfico al lado del otro:

library(patchwork)
plot_sex + plot_island # uno AL LADO del otro

O uno encima del otro:

plot_sex / plot_island # uno ENCIMA de otro

Si ahora creamos otra variable…

scatter_size <- ggplot(data = penguins,
                      mapping = aes(x = flipper_length_mm,
                                    y = body_mass_g,
                                    color = island
                                    )
                ) +
  geom_point() 

💡Podrías adiviar qué hace esta línea?

(plot_sex | plot_island) / scatter_size
(plot_sex | plot_island) / scatter_size
## Warning: Removed 2 rows containing missing values (`geom_point()`).

Con {patchwork}, podemos además, añadir etiquetas a nuestros gráficos

figure <- (plot_sex | plot_island) / scatter_size

#figure + plot_annotation(tag_levels = 'A')

figure + plot_annotation(tag_levels = 'A') &
  theme_bw(base_size = 14)
## Warning: Removed 2 rows containing missing values (`geom_point()`).

Con {papaja} podemos aplicar directamente el estilo APA a un gráfico

#install.packages("papaja")
library(papaja)
## Loading required package: tinylabels
scatter_size + 
  scale_color_brewer(palette = "Set1") +
  labs(x = "flipper length (mm)",
       y = "body mass (g)",
  ) +
  theme_apa(box = TRUE, base_size = 20)
## Warning: Removed 2 rows containing missing values (`geom_point()`).

Además, {papaja} contiene varias funciones que son útiles para preparar nuestros outputs de R para manuscritos. Por ejemplo, la función apa_table convierte tablas al formato APA.

Podemos imprimir solo la tabla:

apa_table(head(penguins))
(#tab:table)
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex year
Adelie Torgersen 39.10 18.70 181 3750 male 2007
Adelie Torgersen 39.50 17.40 186 3800 female 2007
Adelie Torgersen 40.30 18.00 195 3250 female 2007
Adelie Torgersen NA NA NA NA NA 2007
Adelie Torgersen 36.70 19.30 193 3450 female 2007
Adelie Torgersen 39.30 20.60 190 3650 male 2007

O imprimirla directamente con un formato que respeta las normas APA:

apa_table(
  head(penguins)
  , caption = "Table 1"
  , note = "First few rows of the *palmerpenguin* dataset."
  , escape = TRUE
)
(#tab:table-full) Table 1
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex year
Adelie Torgersen 39.10 18.70 181 3750 male 2007
Adelie Torgersen 39.50 17.40 186 3800 female 2007
Adelie Torgersen 40.30 18.00 195 3250 female 2007
Adelie Torgersen NA NA NA NA NA 2007
Adelie Torgersen 36.70 19.30 193 3450 female 2007
Adelie Torgersen 39.30 20.60 190 3650 male 2007

Note. First few rows of the palmerpenguin dataset.

 

También podemos crear tablas de mensajes más complejos como el output de una regresión:

lm_out <- lm(data = penguins, formula = bill_length_mm ~ bill_depth_mm + flipper_length_mm)
summary(lm_out)
## 
## Call:
## lm(formula = bill_length_mm ~ bill_depth_mm + flipper_length_mm, 
##     data = penguins)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -10.8831  -2.7734  -0.3268   2.3128  19.7630 
## 
## Coefficients:
##                    Estimate Std. Error t value Pr(>|t|)    
## (Intercept)       -28.14701    5.51435  -5.104 5.54e-07 ***
## bill_depth_mm       0.62103    0.13543   4.586 6.38e-06 ***
## flipper_length_mm   0.30569    0.01902  16.073  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 4.009 on 339 degrees of freedom
##   (2 observations deleted due to missingness)
## Multiple R-squared:  0.4638, Adjusted R-squared:  0.4607 
## F-statistic: 146.6 on 2 and 339 DF,  p-value: < 2.2e-16
apa_lm <- apa_print(lm_out)
apa_table(
  apa_lm$table
  , caption = "A full regression table."
)
(#tab:unnamed-chunk-11) A full regression table.
Predictor \(b\) 95% CI \(t\) \(\mathit{df}\) \(p\)
Intercept -28.15 [-38.99, -17.30] -5.10 339 < .001
Bill depth mm 0.62 [0.35, 0.89] 4.59 339 < .001
Flipper length mm 0.31 [0.27, 0.34] 16.07 339 < .001
apa_lm$table

O de un ANOVA:

anova_result <- aov(bill_length_mm ~ species, data = penguins) 

apa_anova <- apa_print(summary(anova_result))
## For one-way between subjects designs, generalized eta squared is
##   equivalent to eta squared. Returning eta squared.
apa_table(
  apa_anova
  , caption = "A full regression table."
)
(#tab:unnamed-chunk-12) A full regression table.
Effect \(\hat{\eta}^2_G\) 90% CI \(F\) \(\mathit{df}\) \(\mathit{df}_{\mathrm{res}}\) \(p\)
Species .708 [.669, .740] 410.60 2 339 < .001

El output de apa_table es útil si queremos tener la tabla en formato APA en nuestro reporte de R Markdown. Sin embargo, no es tan útil si queremos el resultado en un word directamente.

Para ello, podemos usar, por ejemplo, el paquete {apaTables} para guardar nuestra tabla en formato .doc:

#install.packages("apaTables",dep=T)
library(apaTables)

table <- apa.aov.table(anova_result, filename = "tablas/anova_table.doc")

table <- apa.reg.table(lm_out, filename = "tablas/regression_table.doc")