r ggplot2 tidyeval

Creación de múltiples gráficos basados en los nombres de columna



ggplot2 tidyeval (1)

Esta es mi primera pregunta en stackoverlow, corríjame si no estoy siguiendo los protocolos de preguntas correctos.

Estoy tratando de crear algunos gráficos para los datos que se han recopilado en tres puntos de tiempo (tiempo 1, tiempo 2, tiempo 3) que equivale a X1 ..., X2 ... y X3 ... al comienzo de los nombres de columna . Los gráficos también están separados por la columna $ Grupo del marco de datos.

No tengo problemas para crear los gráficos, solo tengo muchas variables (~ 170) y quiero comparar el tiempo 1 con el tiempo 2, el tiempo 2 con el tiempo 3, etc., así que estoy tratando de trabajar un atajo para ejecutar este tipo de código. En lugar de tener que escribir cada uno individualmente.

Como se indicó anteriormente, he creado nombres de variables como X1 ... X2 ... que indican el momento en que se registró la variable, es decir, X1BCSTCAT = tiempo 1; X2BCSTCAT = tiempo 2; X3BCSTCAT = tiempo 3. Aquí hay una pequeña muestra de cómo se ven mis datos:

df <- structure(list(ID = structure(1:6, .Label = c("101","102","103","118","119","120"), class = "factor"), Group = structure(c(1L,1L,1L,2L,2L,2L), .Label = c("C8","TC"), class = "factor"), Wave = structure(c(1L, 2L, 3L, 4L, 1L, 2L), .Label = c("A","B","C","D"), class = "factor"), Yr = structure(c(1L, 2L, 1L, 2L, 1L, 2L), .Label = c("3","5"), class = c("ordered", "factor")), Age.Yr. = c(10.936,10.936, 9.311, 10.881, 10.683, 11.244), Training..hr. = c(10.667,10.333, 10.667, 10.333, 10.333, 10.333), X1BCSTCAT = c(-0.156,0.637,-1.133,0.637,2.189,1.229), X1BCSTCR = c(0.484,0.192, -1.309, 0.912, 1.902, 0.484), X1BCSTPR = c(-1.773,0.859, 0.859, 0.12, -1.111, 0.12), X2BCSTCAT = c(1.006, -0.379,-1.902, 0.444, 2.074, 1.006), X2BCSTCR = c(0.405, -0.457,-1.622, 1.368, 1.981, 0.168), X2BCSTPR = c(-0.511, -0.036,2.189, -0.036, -0.894, 0.949), X3BCSTCAT = c(1.18, -1.399,-1.399, 1.18, 1.18, 1.18), X3BCSTCR = c(0.967, -1.622, -1.622,0.967, 0.967, 1.255), X3BCSTPR = c(-1.282, -1.282, 1.539,1.539, 0.792, 0.792)), row.names = c(1L, 2L, 3L, 4L, 5L,8L), class = "data.frame")

Aquí hay un código de trabajo para crear un gráfico utilizando ggplot para datos de tiempo 1 frente a tiempo 2 en una variable:

library(ggplot2) p <- ggplot(df, aes(x=df$X1BCSTCAT, y=df$X2BCSTCAT, shape = df$Group, color = df$Group)) + geom_point() + geom_smooth(method=lm, aes(fill=df$Group), fullrange = TRUE) + labs(title="BCSTCAT", x="Time 1", y = "Time 2") + scale_color_manual(name = "Group",labels = c("C8","TC"),values = c("blue", "red")) + scale_shape_manual(name = "Group",labels = c("C8","TC"),values = c(16, 17)) + scale_fill_manual(name = "Group",labels = c("C8", "TC"),values = c("light blue", "pink"))

Así que realmente estoy tratando de crear una especie de atajo en el que R recorra y haga coincidir los nombres de las variables X1 ... vs X2 ... y así sucesivamente y cree los gráficos. Supongo que debe haber alguna forma de trazar en función de los números de columna coincidentes, por ejemplo, df [, 7] vs df [, 10] e iterar a través de este proceso o trazar al hacer coincidir los nombres (donde la única diferencia en los nombres de variables es el número lo que indica el tiempo).

Anteriormente he realizado el ciclo de creación de gráficos individuales con la función lapply , pero no tengo idea de por dónde empezar, incluso tratando de hacer esto.


Una solución con enfoque tidyeval . Necesitaremos ggplot2 v3.0.0 (recuerde reiniciar su sesión R)

install.packages("ggplot2", dependencies = TRUE)

  • Primero construimos una función que toma los nombres de columnas y grupos como entradas. Tenga en cuenta el uso de rlang::sym , rlang::quo_name & !! .

  • Luego cree 2 vectores de nombre para los valores x- y y- , de modo que podamos recorrerlos simultáneamente usando purrr::map2 .

library(rlang) library(tidyverse) df <- structure(list(ID = structure(1:6, .Label = c("101","102","103","118","119","120"), class = "factor"), Group = structure(c(1L,1L,1L,2L,2L,2L), .Label = c("C8","TC"), class = "factor"), Wave = structure(c(1L, 2L, 3L, 4L, 1L, 2L), .Label = c("A","B","C","D"), class = "factor"), Yr = structure(c(1L, 2L, 1L, 2L, 1L, 2L), .Label = c("3","5"), class = c("ordered", "factor")), Age.Yr. = c(10.936,10.936, 9.311, 10.881, 10.683, 11.244), Training..hr. = c(10.667,10.333, 10.667, 10.333, 10.333, 10.333), X1BCSTCAT = c(-0.156,0.637,-1.133,0.637,2.189,1.229), X1BCSTCR = c(0.484,0.192, -1.309, 0.912, 1.902, 0.484), X1BCSTPR = c(-1.773,0.859, 0.859, 0.12, -1.111, 0.12), X2BCSTCAT = c(1.006, -0.379,-1.902, 0.444, 2.074, 1.006), X2BCSTCR = c(0.405, -0.457,-1.622, 1.368, 1.981, 0.168), X2BCSTPR = c(-0.511, -0.036,2.189, -0.036, -0.894, 0.949), X3BCSTCAT = c(1.18, -1.399,-1.399, 1.18, 1.18, 1.18), X3BCSTCR = c(0.967, -1.622, -1.622,0.967, 0.967, 1.255), X3BCSTPR = c(-1.282, -1.282, 1.539,1.539, 0.792, 0.792)), row.names = c(1L, 2L, 3L, 4L, 5L,8L), class = "data.frame") # define a function that accept strings as input pair_plot <- function(x_var, y_var, group_var) { # convert strings to symbols x_var <- rlang::sym(x_var) y_var <- rlang::sym(y_var) group_var <- rlang::sym(group_var) # unquote symbols using !! ggplot(df, aes(x = !! x_var, y = !! y_var, shape = !! group_var, color = !! group_var)) + geom_point() + geom_smooth(method = lm, aes(fill = !! group_var), fullrange = TRUE) + labs(title = "BCSTCAT", x = rlang::quo_name(x_var), y = rlang::quo_name(y_var)) + scale_color_manual(name = "Group", labels = c("C8", "TC"), values = c("blue", "red")) + scale_shape_manual(name = "Group", labels = c("C8", "TC"), values = c(16, 17)) + scale_fill_manual(name = "Group", labels = c("C8", "TC"), values = c("light blue", "pink")) + theme_bw() } # Test if the new function works pair_plot("X1BCSTCAT", "X2BCSTCAT", "Group")

# Create 2 parallel lists list_x <- colnames(df)[-c(1:6, (ncol(df)-2):(ncol(df)))] list_x #> [1] "X1BCSTCAT" "X1BCSTCR" "X1BCSTPR" "X2BCSTCAT" "X2BCSTCR" "X2BCSTPR" list_y <- lead(colnames(df)[-(1:6)], 3)[1:length(list_x)] list_y #> [1] "X2BCSTCAT" "X2BCSTCR" "X2BCSTPR" "X3BCSTCAT" "X3BCSTCR" "X3BCSTPR" # Loop through 2 lists simultaneously # Supply inputs to pair_plot function using purrr::map2 map2(list_x, list_y, ~ pair_plot(.x, .y, "Group"))

Salidas de muestra:

#> [[1]]

#> #> [[2]]

Creado en 2018-05-24 por el paquete reprex (v0.2.0).