Construção de um aplicativo no R com Shiny & flexdashboard

Como fazer uma visualização comparativa e interativa do desempenho dos participantes da 1ª Etapa do PAS 2018

Guilherme Viana
Data Hackers
10 min readJul 2, 2019

--

Captura de tela do aplicativo finalizado

Este tutorial tem os seguintes pré-requisitos:

  • Nível intermediário em R;
  • Familiaridade com o pacote tidyverse, em especial dplyr e ggplot2, assim como com o operador %>%.

Introdução

No post passado resolvemos o problema de transformar um arquivo não tratado, de formato PDF, em uma base de dados tratada e pronta para uso, utilizando os resultados da 1ª etapa do PAS 2018. Os scripts estão em meu perfil no GitHub, inclusive os resultados em Excel.

Como disse anteriormente, a limpeza e tratamento dos dados fazem parte da primeira fase de um projeto de análise de dados, e é uma fase recursiva, ou seja, à medida que avançamos nas etapas da análise, precisamos sempre voltar a esse processo e aperfeiçoá-lo, tanto para corrigir erros que não identificamos inicialmente (erros de digitação, pontuação sobrando, um número que está como texto, etc.) quanto para moldar a base de dados às nossas necessidades (criação de novas variáveis, aplicação de filtros, ordenação das observações, etc.) — todos esses esforços são o ponto de início da análise exploratória dos dados ou EDA (Exploratory Data Analysis).

Aqui vou aproveitar para destacar a importância de manter um script, isto é, a sequência dos códigos utilizados para chegar a determinado resultado, pois essa é uma das principais vantagens que linguagens como o R e Python têm, especialmente para iniciantes em programação. É o script que te permitirá construir um fluxo de trabalho adequado, com as ações sequenciais necessárias, além do poder de recomeçar a análise e executar todo o código novamente, caso algo dê errado.

Pedaço do script utilizado para tratar o PDF original

Motivação

Voltando ao foco deste artigo, que é a construção do painel comparativo, vamos iniciar com a inspeção da base de dados dos resultados.

A base de dados dos resultados, no RStudio

Temos muitas observações (22.669 candidatos que fizeram a prova), mas poucas variáveis:

  • Inscrição: número de inscrição do candidato;
  • Nome: nome do candidato;
  • EscoreBruto1: nota da Parte 1, na prova de língua estrangeira;
  • EscoreBruto2: nota da Parte 2, na prova de artes cênicas, artes visuais, biologia, filosofia, geografia, história, língua portuguesa, literatura, matemática, música, química e sociologia;
  • SomaEB: soma dos escores brutos 1 e 2;
  • NotaD: nota dos itens do Tipo D, que são questões discursivas (abertas);
  • NotaRedação: nota da prova de redação.

Ou seja, não temos informações adicionais dos candidatos além de suas notas nas provas. O que fazer com isso? Bom, se eu fosse um dos concorrentes à vaga na UnB, sem dúvidas gostaria de descobrir como foi meu desempenho em relação aos demais participantes. E é isso que vamos fazer!

Análise dos resultados

Temos então que cinco das sete variáveis correspondem às notas dos candidatos. É importante que essas notas sejam, de fato, notas, no sentido de serem variáveis numéricas. Para verificar isso de forma rápida, podemos utilizar o comando str, que mostra a estrutura dos dados. Conforme a figura abaixo, a base notasPAS tem 22.669 observações e 7 variáveis, sendo Inscrição e Nome variáveis de texto (chr ou character) e as demais numéricas (num ou numeric).

Estrutura dos dados

Estrutura correta, o próximo passo é explorar a distribuição das variáveis, com a função summary, que nos dá as estatísticas de posição dos resultados, isto é, mínimo, primeiro quartil (Q1), mediana (Q2), média, terceiro quartil (Q3) e máximo; retirei as duas primeiras colunas, que correspondem às variáveis de texto.

Revisão de conceitos

mínimo é o menor valor; primeiro quartil é o valor que representa 25% dos dados; mediana é o valor que representa 50% dos dados; média é a soma de todos os valores dividida pelo número de observações; terceiro quartil é o valor que representa 75% dos dados; e máximo é o maior valor da variável de interesse. Em todos os casos, exceto o da média, é necessário ordenar os valores de forma a calcular as medidas.

Estatísticas de posição dos resultados

Uma primeira inspeção das estatísticas mostra que todas as notas são variáveis numéricas contínuas. Variáveis numéricas podem ser discretas ou contínuas. O caso discreto pressupõe que os valores admitidos para aquela variável sejam inteiros, como, por exemplo, o número de pessoas atendidas, a quantidade de livros em sua casa, etc. Já uma variável numérica contínua pode ser representada por números fracionários, como no nosso caso das notas.

Analisando agora as estatísticas das notas, podemos tirar algumas conclusões. A primeira nota, o EscoreBruto1, varia de zero a 9,823, com mediana (2,679) e média (2,734) bem próximas, e terceiro quartil igual a 4,465, ou seja, 75% dos participantes tiraram, no máximo, esse valor na prova de língua estrangeira. De acordo com o Guia da 1ª Etapa do PAS, são dez os itens dessa prova, então alguém quase gabaritou esses itens — o valor máximo de 9,823.

O EscoreBruto2, que corresponde à nota nos demais itens, exceto línguas estrangeiras e questões Tipo D, teve mínimo zero e média (22,77) e mediana (21,43) próximas, semelhante ao EscoreBruto1; o terceiro quartil não ficou muito longe da mediana, indicando que apenas 25% dos candidatos obtiveram nota maior que 30,51. E a maior nota, nessa prova, foi de 75,91, o que é bem alto, considerando os critérios do Cebraspe de penalizar itens errados.

A variável SomaEB representa a soma das notas das provas 1 e 2. Suas estatísticas são bem semelhantes as do EscoreBruto2, pois a maioria (75%) dos candidatos ficou com, no máximo, 33,93 pontos. O máximo foi a medida que mais mudou, passando para 85,73, que é, por acaso, a soma das notas máximas, ou seja, o mesmo estudante tirou 9,823 na prova de línguas e 75,91 no restante dos itens.

Está de parabéns, né não?

A questão discursiva, NotaD, deixou de ser respondida por pelo menos 25% dos participantes (primeiro quartil igual a zero). O desempenho mediano foi de 0,446, menor que o desempenho médio, de 0,7478, e 75% dos candidatos obteve até 1,34 nessa questão, que vale 3. A maior nota foi 2,679 [será que foi do mesmo estudante?].

Por fim, vemos a nota da redação, na qual 25% dos estudantes tiraram pelo menos 4,583 de 10. A nota mediana foi ligeiramente maior, 5,881, e a nota média, 5,741. Os 25% candidatos de melhor desempenho obtiveram notas iguais ou maiores que 7,16, enquanto que a nota máxima foi, literalmente, máxima, 10.

Parece que terminamos de explorar as notas, mas eu diria que ainda há uma possibilidade: a nota total do candidato. Vamos criá-la e calcular suas estatísticas de posição.

Estatísticas de posição incluindo a nota total

A nota total corresponde à soma das variáveis SomaEB, NotaD e NotaRedação, que foram representadas pela posição 5:7 (colunas 5 a 7) no mutate que criou a variável NotaTotal; aqui vale destacar o uso da função rowSums, pois queremos a soma das notas de cada candidato, ou seja, em sua própria linha (row). De todos os candidatos participantes, 25% tiraram até 20,72 de 110, com mínimo de zero pontos. A mediana foi de 30,2, e a média, 32. Os 25% estudantes de melhor desempenho tiraram, no mínimo, 41,43 pontos. Já a nota máxima foi de 97,61, considerando todas as avaliações somadas. Essa variável nos dá a noção do desempenho global dos candidatos na 1ª etapa do PAS, e a usaremos para comparar o desempenho dos participantes.

Visualização dos resultados

Variáveis contínuas, como as notas, são melhor representadas por dois tipos de gráficos: o boxplot e o histograma. Considerando que o boxplot trata-se da representação gráfica das medidas de posição, que foram extensivamente discutidas acima, vamos escolher o histograma para a visualização das notas dos participantes e sua posterior comparação.

Histograma usando ggplot2

Decidido o tipo de gráfico, podemos fazer um primeiro esboço do histograma das notas totais, para visualizarmos o que será gerado e ir adaptando.

Primeira versão do histograma. Claramente.

Uma importante decisão ao criamos um histograma é o número de barras, ou bins. Há algumas regras que podemos seguir, mas como nosso foco será no desempenho individual, em comparação ao desempenho global, podemos simplificar essa etapa e escolher empiricamente o número de barras. Considerando que as notas da prova 1 e da redação variam de 0 a 10, e a nota geral variou de 0 a (quase) 100, vamos definir dez barras para nossos histogramas, e já fazer vários ajustes estéticos.

Versão melhorada do primeiro histograma

Está visualmente agradável o resultado. Agora precisamos inserir a parte comparativa, na qual o estudante verá sua posição no histograma, assim como um pequeno texto explicando seu desempenho. Para testar isso no nosso histograma, vamos escolher um candidato aleatório, definir o texto a ser utilizado, e inserir esses elementos no gráfico.

Gráfico finalizado com todos os elementos necessários.

Terminamos de fazer o gráfico do jeito esperado: histograma mostrando a distribuição geral e apontando o desempenho do candidato, tanto visualmente (linha vermelha) quanto textualmente (título do gráfico). Agora só nos falta montar o painel mostrando todas as notas e comparações.

Montagem do painel

Vamos utilizar o shiny, juntamente com o pacote flexdashboard, para montar o painel de comparação de desempenho dos candidatos da 1ª etapa do PAS 2018. Para tal, utilizei a página de ajuda do próprio flexdashboard. A ideia é montar um arquivo RMarkdown interativo utilizando o template do flexdashboard, e adicionar a opção runtime: shiny no cabeçalho do arquivo (conhecido como YAML). A parte interativa ficará por conta do shiny, que permitirá a seleção dos candidatos e atualização relativa dos gráficos. O cabeçalho do aplicativo está comentado abaixo. Ok, mas como começa?

Oi?

Primeiro passo é instalar o pacote flexdashboard. O primeiro passo depois desse é criar um novo documento, em File > New File > R Markdown… > From Template > Flex Dashboard. Isso criará um esqueleto, que vamos modificar para nossas necessidades. O flexdashboard serve basicamente para dividirmos o documento em seções, que podem ser colunas ou linhas. A ideia é ter quatro gráficos, sendo dois na parte de cima (primeira linha) e dois na parte de baixo (segunda linha), assim como uma seção de introdução do projeto e escolha do candidato a ser visualizado.

Todo documento RMarkdown tem o pedaço (chunk) de código global, em que carregamos os pacotes necessários e a base a ser utilizada pelo documento, além de suas opções gerais. E é o que faremos.

A barra lateral, que fará a introdução do trabalho e permitirá a seleção do candidato, de forma a permitir a comparação de seu desempenho, é feita adicionando o elemento do flexdashboard Inputs {.sidebar}. A função selectInput, do shiny, insere o botão de escolha do candidato. Abaixo do código foi feita a descrição do projeto.

Agora vamos inserir os gráficos, dois por linha, totalizando quatro gráficos das notas — prova 1, prova 2, redação e nota total. Primeiro criamos a linha, com o comando Row. Em seguida inserimos o código criado anteriormente, com algumas adaptações: utilizar a função do shiny renderText para criação do texto referente à cada variável, e renderPlot para criação dos gráficos. A única complementação, em relação ao código anterior, foi o aumento do tamanho da fonte do título.

E é isso, terminamos o script e podemos executá-lo no RStudio para testar o aplicativo, utilizando o botão “Run Document”. Isso abrirá o visualizador do próprio programa, mostrando o aplicativo pronto para utilização.

Aperte o botão para gerar o aplicativo internamente

No entanto essa versão é apenas interna, pois ninguém além de você conseguirá acessá-la. Para tornar o aplicativo público, há duas etapas preliminares: 1) criar uma conta no site shinyapps.io; e 2) seguir um breve tutorial; tais etapas garantem a utilização de um servidor shiny para rodar os códigos no navegador preferido (chrome, mozilla, edge, etc.) do consumidor da informação e garantir a interatividade do relatório. Feito isso, a publicação do app é feita dentro do próprio RStudio, ao clicarmos no símbolo azul destacado abaixo, e seguindo as instruções que surgirem.

Botão, no RStudio, para publicação no shinyapps.io

O painel resultante deste artigo está disponível para consulta na minha página do shinyapps, e o código completo está no GitHub.

Considerações finais

O aplicativo de comparação de desempenho teve início como um simples problema: a transformação de um arquivo em PDF em uma base de dados tratada e utilizável. Com o sucesso da leitura do PDF, novas possibilidades de análise surgiram — a análise exploratória dos dados (EDA) foi realizada, e vislumbrou-se a possibilidade de comparar o desempenho dos participantes. Para esse fim, foi criado um histograma que mostrou, ao mesmo tempo, a distribuição da população e a nota do candidato, mostrando sua posição em relação a todos os participantes.

Para disponibilizar essa comparação aos estudantes que fizeram a prova da 1ª etapa do PAS 2018, pensou-se em um aplicativo shiny publicado online, que foi feito utilizando o pacote flexdashboard, para torná-lo um painel interativo. E o resultado de todo esse fluxo foi publicado e está acessível gratuitamente.

Com isso, finalizo por aqui. Obrigado por ficar até o fim, e até a próxima!

Meus contatos: IG, Twitter, GitHub

--

--

Guilherme Viana
Data Hackers

Estatístico, mestre em Adm, doutorando em Economia na UnB. Principais interesses: programação com R, análise & visualização de dados, dogs e jogos de RPG