alt text

GET00183 - Visualização de Dados

Jony Arrais Pinto Junior

Para melhorar ainda mais as visualizações de dados produzidas, podemos criar no R painéis interaivos. Que podem servir como uma ferramenta poderosa para o entendimento dos resultados obtidos nas análises.

1 - Shiny

O shiny é um pacote do R que facilita a construção de aplicativos (apps) interativos da web direto do R. Este material nos ajudará a começar a construir aplicativos Shiny imediatamente.

Podemos enxergar o shiny como um sistema para desenvolvimento de aplicações web usando o R, um pacote do R (shiny) e um servidor web (shiny server). Vale ressaltar aqui, que o shiny não é uma página web.

2.1 - Como criar um primeiro App

Instale o pacote shiny. Após a instalação, no Rstudio, acesse os menus File > New File > Shiny Web App… Você verá a seguinte janela:

Figura 1: Criando um primeiro App no Shiny.

Figura 1: Criando um primeiro App no Shiny.

A janela acima permite que seja definido o nome (sem caractéres especiais e espaço) e o diretório no qual desejamos salvar o App. Após preencher os dois campos, clique em create. Após isso um exemplo será carregado. Para executar o App você precisará clicar em Runn App como indicado abaixo:

Figura 2: Exemplo carregado automaticamente no shiny.

Figura 2: Exemplo carregado automaticamente no shiny.

Após a execução, uma nova janela será aberta e ela contém as análises realizadas no exemplo que foi carregado automaticamente, como apresentado a seguir:

Figura 3: App executado.

Figura 3: App executado.

No exemplo executado, temo um App que cria um histograma e permite que o usuário escolha o número de bins. Por enquanto não estamos entrando em detalhes nos objetos carregados no exemplo, já discutiremos tais objetos.

É importante ressaltar que seguindo o caminho indicado acima estamos criando um App.Uma outra possibilidade é criarmos uma apresentação ou documento com o shiny. O caminho será familiar para a gente, pois usaremos o R Markdown para isso. No Rstudio, acesse os menus File > New File > R Markdown… Você verá a seguinte janela:

Figura 4: Criando um documento shiny.

Figura 4: Criando um documento shiny.

Na janela apresentada, escolha no menu a esquerda a opção Shiny e defina o título e o autor. Existem duas opções: o ducumento e a apresentação. Para executar, clique em Run Document, como apresentado abaixo:

Figura 5: Exemplo de documento shiny criado automaticamente.

Figura 5: Exemplo de documento shiny criado automaticamente.

2.2 - Discutindo o exemplo inicial

O exemplo inicial carregado automaticamente quando criamos o primeiro App é o que se encontra abaixo:

#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
#    http://shiny.rstudio.com/
#

library(shiny)

# Define UI for application that draws a histogram
ui <- fluidPage(

    # Application title
    titlePanel("Old Faithful Geyser Data"),

    # Sidebar with a slider input for number of bins 
    sidebarLayout(
        sidebarPanel(
            sliderInput("bins",
                        "Number of bins:",
                        min = 1,
                        max = 50,
                        value = 30)
        ),

        # Show a plot of the generated distribution
        mainPanel(
           plotOutput("distPlot")
        )
    )
)

# Define server logic required to draw a histogram
server <- function(input, output) {

    output$distPlot <- renderPlot({
        # generate bins based on input$bins from ui.R
        x    <- faithful[, 2]
        bins <- seq(min(x), max(x), length.out = input$bins + 1)

        # draw the histogram with the specified number of bins
        hist(x, breaks = bins, col = 'darkgray', border = 'white')
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

Um App Shiny tem dois componentes básicos: a interface de usuário (ui) e o servidor (server).

A interface de usuário diz respeito à construção do código HTML que compõe o app. Podemos pensar que neste componente incluímos a programação do código HTML daquilo que será apresentado na tela, ou seja, a interface do seu app.

Já o segundo componente diz respeito àquilo que não será visto por quem utilizar o app: o servidor. O servidor contém toda a lógica para a construção das saídas apresentadas na ui.

Um aplicativo em shiny será composto por: um objeto chamado ui, uma função server e outra chamada shinyApp.

Como dito anteriormente, no objeto ui contruímos basicamente o que será apresentado na interface para o usuário. Por exemplo, é aqui que construímos o layout, definimos as visualizações que serão apresentadas (gráfico, tabelas, mapas) e podemos definir elementos de CSS e JavaScript, se assim desejarmos. As funções usadas para a construção de ui retornam códigos HTML, logo, podemos ver ui como um grande bloco de códigos HTML.

O server é que atual no plano de fundo. A função server vai receber os códigos em R, que estamos habituados a trabalhar, para manipular bases, gerar tabelas, gráficos, mapas e qualquer outra visualização que quisermos construir.

A função server poderá contar com os seguintes argumentos: input (uma lista com todos os parâmetros que o usuário pode interagir), output (uma lista com todas as visualizações que serão apresentadas para o usuário) e session (uma lista com as informações da sessão).

Os outputs representam as saídas do nosso App. Deste modo, tudo que queremos que nosso código R retorne para o usuário será um output. Essas saídas podem ser tabelas, gráficos, mapas, texto, imagens ou qualquer outro elemento em HTML.

Os outputs são definidos no ui e criados no server. Cada tipo de output é definido por uma função do tipo …Output(). Veja as principais: imageOutput (imagens), plotOutput (gráficos), tableOutput (tabelas) e textOutput (textos).

Para criar um output, precisamos das funções do tipo render_(). Essas funções são responsáveis por conectar as nossas visualizações criadas pelo R com o código HTML do ui. Na grande maioria dos casos, teremos o par visualizacaoOutput() renderVisualizacao().

No exemplo acima, o objeto distPlot foi criado dentro do server com os códigos usuais do R e foi indicado no objeto ui para visualização no plotOutut.

Além disso, foi definido uma barra lateral com entrada de controle deslizante para o número de intervalos de classes.

Atividade: Crie um novo app que faz o mesmo histograma do exemplo, mas usando o ggplot2. Acrescente uma cor no histograma e coloque os rótulos do App em português.

2 - Inputs (controle ao usuário)

Os inputs permitem que o usuário interaja com o App criado. Eles são criados dentro do objeto ui por meio de funções do tipo _Input(). Dentro do server, os inputs são utilizados para alterar as visualizações.

Abaixo são apresentados alguns exemplos.

Figura 6: Exemplo retirado de rstudio.com/shiny/.

Figura 6: Exemplo retirado de rstudio.com/shiny/.

Acesse este link para testar como os diferentes inputs funcionam. Você pode ver a inclusão deles nos dois objetos: server e ui.

Abaixo, vamos voltar ao App e fazer algumas modificações, como a sugerida na atividade, ou seja, transformar ele em um gráfico do ggplot2.

# Carregando pacotes
library(shiny)
library(tidyverse)

# Importando os dados
survey = read_csv2("survey85.csv")

# Definindo o objeto UI no App para a criação do histograma
ui <- fluidPage(

    # Titúlo do App
    titlePanel("Idade"),

    # Incluindo uma barra lateral que permite o usuário definir o número de intervalos 
    sidebarLayout(
        sidebarPanel(
            sliderInput("intervalos",
                        "Número de intervalos:",
                        min = 1,
                        max = 30,
                        value = 15)
        ),

        # Mostra o gráfico
        mainPanel(
           plotOutput("distPlot")
        )
    )
)

# Definindo a lógica do server necessária para construir o histograma
server <- function(input, output) {

    output$distPlot <- renderPlot({
        # gera o número de interevalos com base em input$intervalos de ui.R
        x    <- survey$idade
        intervalos <- seq(min(x), 
                          max(x), 
                          length.out = input$intervalos + 1)

        # faz o histograma com o número de intervalos especificados
        ggplot(data = survey,
               mapping = aes(x = idade)) +
            geom_histogram(breaks = intervalos,
                           color = "white",
                           fill = "red") +
            theme_classic() +
            labs(x = "Idade",
                 y = "Frequência")
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

Usando outros inputs… O exemplo abaixo permite criar gráficos de frequências de polígonos de amostras de duas distribuições normais. No App você escolhe o tamanho da amostra, a média e a variância de cada distribuição.

# Carregando pacotes
library(shiny)
library(tidyverse)

freqpoly <- function(x1, x2, binwidth = 0.1, xlim = c(-3, 3)) {
  df <- data.frame(
    x = c(x1, x2),
    g = c(rep("x1", length(x1)), rep("x2", length(x2)))
  )

  ggplot(df, aes(x, colour = g)) +
    geom_freqpoly(binwidth = binwidth, size = 1) +
    coord_cartesian(xlim = xlim)
}

# criando o objeto ui
ui <- fluidPage(
  fluidRow(
    column(4, 
      "Distribution 1",
      numericInput("n1", label = "n", value = 1000, min = 1),
      numericInput("mean1", label = "µ", value = 0, step = 0.1),
      numericInput("sd1", label = "σ", value = 0.5, min = 0.1, step = 0.1)
    ),
    column(4, 
      "Distribution 2",
      numericInput("n2", label = "n", value = 1000, min = 1),
      numericInput("mean2", label = "µ", value = 0, step = 0.1),
      numericInput("sd2", label = "σ", value = 0.5, min = 0.1, step = 0.1)
    ),
    column(4,
      "Frequency polygon",
      numericInput("binwidth", label = "Bin width", value = 0.1, step = 0.1),
      sliderInput("range", label = "range", value = c(-3, 3), min = -15, max = 15)
    )
  ),
  fluidRow(
    column(9, plotOutput("hist"))
  )
)

# Criando o objeto server
server <- function(input, output, session) {
  output$hist <- renderPlot({
    x1 <- rnorm(input$n1, input$mean1, input$sd1)
    x2 <- rnorm(input$n2, input$mean2, input$sd2)
    
    freqpoly(x1, x2, binwidth = input$binwidth, xlim = input$range)
  }, res = 96)
}

# Run the application 
shinyApp(ui = ui, server = server)

Atividade: Modifique o App acima, incluindo uma terceira distribuição. Faça com que uma as duas primeiras sejam normais e a terceira uma t.