Referenciar nomes dos elementos em gráficos

Olá!

Tenho uma lista de várias tibbles, referentes à um sumário de dados para três meses:

> summary(lista)
    Length Class  Mode
FEV 2      tbl_df list
MAR 2      tbl_df list
ABR 2      tbl_df list

Vou precisar rodar um map() desta lista para uma função de gráfico,
como:
map(lista, funcao_grafico)

Esta função usa o ggplot2, e será inserido uma caption em cada gráfico para identificar o mês de referência. No entanto, não há referência à nenhum mês nas colunas das tibbles. O único lugar que existe o nome do mês é no próprio nome do elemento da lista

> names(lista)
[1] "FEV" "MAR" "ABR"

Como posso inserir um subtitle ou caption no ggplot2, de forma que cada gráfico faça referência ao respectivo nome do objeto que está sendo mapeado na função? Ou ainda, permitir que eu crie separadamente estes nomes e que sejam utilizados sequencialmente na função?

2 curtidas

A função imap do purrr serve exatamente para isso. Exemplo:

x <- list(
  a = 1,
  b = 2,
  c = 3
)

z <- purrr::imap(x, function(valor, nome) {
  print(nome)
  print(valor)
})
#> [1] "a"
#> [1] 1
#> [1] "b"
#> [1] 2
#> [1] "c"
#> [1] 3

Created on 2020-05-05 by the reprex package (v0.3.0)

3 curtidas

O Guilherme pediu para dar um exemplo com {ggplot} em aula, então montei esse reprex:

library(tidyverse)

faz_grafico <- function(base, nome) {
  base %>% 
    ggplot(aes(x = mpg, y = disp)) +
    geom_point() +
    labs(title = nome)
}

lista <- list(titulo1 = mtcars, 
              titulo2 = mtcars, 
              titulo3 = mtcars)

graficos <- imap(lista, faz_grafico)

graficos[[1]]

# se quiser juntar todos os gráficos em uma figura só
library(patchwork)

wrap_plots(graficos, ncol = 2)

Created on 2020-05-07 by the reprex package (v0.3.0)

4 curtidas

Perfeito, @dfalbel e @jtrecenti, fez total sentido

Aproveitando a pergunta, se eu quiser ao invés de plotar os gráficos lado a lado, usar um facet_wrap, diferenciando os dados contidos nas tabelas “titulo1”, “titulo2”, “titulo3” (variáveis iguais porém observações diferentes), a solução mais viável seria empilhar todos estes dfs e tratar como um único elemento, ou existe algo mais fácil?

Agradeço a ajuda

Acho que a solução de empilhar seria boa, mesmo. E não fica muito difícil se usar as funções enframe() com unnest():

library(tidyverse)

lista <- list(titulo1 = mtcars, 
              titulo2 = mtcars, 
              titulo3 = mtcars)

lista %>%
  enframe("nome", "dados") %>%
  unnest(dados) %>%
  ggplot(aes(x = mpg, y = disp)) +
  geom_point() +
  facet_wrap(~nome, ncol = 2)

image

2 curtidas

Show de bola Athos, ajudou :call_me_hand: