Importância da apresentação dos dados
O trabalho de quem analisa dados vai muito além de planejar, resumir e interpretar observações: apresentar bem os resultados é parte essencial de qualquer projeto ou pesquisa. Não é à toa que já existe até uma área dentro da ciência de dados focada nisso, com o título de "Data Artist".
Além dos pacotes que ajudam a apresentar as figuras geradas nas análises (como mostrei nos posts sobre a qualidade do ajuste de modelos e sobre avaliar o ajuste pela abordagem bayesiana), contamos com pacotes que apresentam tabelas de forma elegante e até interativa.
Seja escrevendo relatórios em \(\LaTeX\), RMarkdown ou até um aplicativo Shiny, este post reúne algumas alternativas para deixar essas tabelas bonitas e informativas. Se você também cuida da formatação do documento em si, veja o post sobre o template Tufte no RMarkdown.
TL;DR
- DT e rhandsontable: tabelas interativas, ótimas para HTML e Shiny.
- formattable e kableExtra: formatação condicional (cores, barras, ícones) em tabelas estáticas.
- sparkline: mini gráficos embutidos direto nas células.
Pacote DT
O pacote DT é uma excelente opção quando se trata de incluir tabelas de dados em relatórios Rmarkdown, o pacote esta hospedado neste link no github, veja a seguir um simples exemplo de uso:
# install.packages("DT") #caso ainda nao tenha o pacote instalado
DT::datatable(iris[1:20, c(5, 1:4)], rownames = FALSE)
Com este link do manual no CRAN é possível entender melhor o funcionamento do pacote e conferir mais exemplos de uso.
Pacote formattable
Este pacote é repleto de funcionalidades interessantes para a formatação dos resultados dispostos em tabelas, também está hospedado no github, podendo ser instalado pelo CRAN ou com os comandos:
# Instalando pelo github
# library(devtools)
# devtools::install_github("renkun-ken/formattable")
library(formattable)Com o pacote carregado vamos conferir algumas das funcionalidades básicas:
#Exemplo de formatação para resultados de porcentagem:
percent(c(0.1, 0.02, 0.03, 0.12))## [1] 10.00% 2.00% 3.00% 12.00%#Exemplo de formatação para resultados de na casa do milhar:
accounting(c(1000, 500, 200, -150, 0, 1200))## [1] 1,000.00 500.00 200.00 (150.00) 0.00 1,200.00Vamos criar um data.frame para ilustrar algumas das funcionalidades do pacote:
#criando um data.frame
df <- data.frame(
id = 1:10,
Nomes = c("Sofia", "Kiara", "Dunki", "Edgar", "Emilia","Gertrudes", "Genovena", "Champanhe", "Amora", "Penelope"),
Kilos = accounting(c(20000, 30000, 50000, 70000, 47000,80000,45000,35000,20000,25000), format = "d"),
Crescimento = percent(c(0.1, 0.2, 0.5, 0.95, 0.97,0.45,0.62,0.57,0.37, 0.3), format = "d"),
Suficiente = formattable(c(T, F, T, F, T,F,F,T,T,F), "Sim", "Não"))Com esses resultados, vejamos um exemplo de tabela que pode ser criada para apresentar esses resultados com o pacote:
formattable(df, list(
id = color_tile("white", "orange"),
Suficiente = formatter("span", style = x ~ ifelse(x == T,
style(color = "green", font.weight = "bold"), NA)),
area(col = c(Kilos)) ~ normalize_bar("lightgrey", 0.2),
Crescimento = formatter("span",
style = x ~ style(color = ifelse(rank(-x) <= 3, "green", "gray")),
x ~ sprintf("%.2f (rank: %02g)", x, rank(-x)))
))| id | Nomes | Kilos | Crescimento | Suficiente |
|---|---|---|---|---|
| 1 | Sofia | 20,000 | 0.10 (rank: 10) | Sim |
| 2 | Kiara | 30,000 | 0.20 (rank: 09) | Não |
| 3 | Dunki | 50,000 | 0.50 (rank: 05) | Sim |
| 4 | Edgar | 70,000 | 0.95 (rank: 02) | Não |
| 5 | Emilia | 47,000 | 0.97 (rank: 01) | Sim |
| 6 | Gertrudes | 80,000 | 0.45 (rank: 06) | Não |
| 7 | Genovena | 45,000 | 0.62 (rank: 03) | Não |
| 8 | Champanhe | 35,000 | 0.57 (rank: 04) | Sim |
| 9 | Amora | 20,000 | 0.37 (rank: 07) | Sim |
| 10 | Penelope | 25,000 | 0.30 (rank: 08) | Não |
Para entender melhor o funcionamento do pacote e conferir mais exemplo de uso confira o manual de introdução ao pacote e manual do pacote, ambos disponíveis no CRAN.
O pacote knitr e kabbleExtra
O pacote knitr permite o uso da função kable() que produz tabelas parecidas com as apresentadas com o pacote DT, porém trás diversas outras funcionalidades que podem ser combinadas com as funcionalidades de outros pacotes, como o kableExtra e até mesmo o formattable apresentado acima.
Os exemplos aqui apresentados foram retirados (sem alterações) do manual do pacote no CRAN
#Carregando pacotes
library(knitr)
library(kableExtra)
#Carregando pacote para ajudar na manipulação dos dados:
library(dplyr)
mtcars[1:10, 1:2] %>%
mutate(
car = row.names(.),
# Você não precisa de formato = "html" se você já definiu opções (knitr.table.format)
mpg = cell_spec(mpg, "html", color = ifelse(mpg > 20, "red", "blue")),
cyl = cell_spec(cyl, "html", color = "white", align = "c", angle = 45,
background = factor(cyl, c(4, 6, 8),
c("#666666", "#999999", "#BBBBBB")))) %>%
select(car, mpg, cyl) %>%
kable("html", escape = F) %>%
kable_styling("striped", full_width = F)| car | mpg | cyl |
|---|---|---|
| Mazda RX4 | 21 | 6 |
| Mazda RX4 Wag | 21 | 6 |
| Datsun 710 | 22.8 | 4 |
| Hornet 4 Drive | 21.4 | 6 |
| Hornet Sportabout | 18.7 | 8 |
| Valiant | 18.1 | 6 |
| Duster 360 | 14.3 | 8 |
| Merc 240D | 24.4 | 4 |
| Merc 230 | 22.8 | 4 |
| Merc 280 | 19.2 | 6 |
#Outro exemplo colorido legal:
iris[1:10, ] %>%
mutate_if(is.numeric, function(x) {
cell_spec(x, "html", bold = T, color = spec_color(x, end = 0.9),
font_size = spec_font_size(x))
}) %>%
mutate(Species = cell_spec(
Species, "html", color = "white", bold = T,
background = spec_color(1:10, end = 0.9, option = "A", direction = -1)
)) %>%
kable("html", escape = F, align = "c") %>%
kable_styling("striped", full_width = F)| Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
|---|---|---|---|---|
| 5.1 | 3.5 | 1.4 | 0.2 | setosa |
| 4.9 | 3 | 1.4 | 0.2 | setosa |
| 4.7 | 3.2 | 1.3 | 0.2 | setosa |
| 4.6 | 3.1 | 1.5 | 0.2 | setosa |
| 5 | 3.6 | 1.4 | 0.2 | setosa |
| 5.4 | 3.9 | 1.7 | 0.4 | setosa |
| 4.6 | 3.4 | 1.4 | 0.3 | setosa |
| 5 | 3.4 | 1.5 | 0.2 | setosa |
| 4.4 | 2.9 | 1.4 | 0.2 | setosa |
| 4.9 | 3.1 | 1.5 | 0.1 | setosa |
Mais um exemplo, dessa vez integrando com o pacote formattable:
#Integrando com formattable
suppressMessages(library(formattable))
mtcars[1:5, 1:4] %>%
mutate(
car = row.names(.),
mpg = color_tile("white", "orange")(mpg),
cyl = cell_spec(cyl, "html", angle = (1:5)*60,
background = "red", color = "white", align = "center"),
disp = ifelse(disp > 200,
cell_spec(disp, "html", color = "red", bold = T),
cell_spec(disp, "html", color = "green", italic = T)),
hp = color_bar("lightgreen")(hp)
) %>%
select(car, everything()) %>%
kable("html", escape = F) %>%
kable_styling("hover", full_width = F) %>%
column_spec(5, width = "3cm") %>%
add_header_above(c(" ", "Hello" = 2, "World" = 2))| car | mpg | cyl | disp | hp |
|---|---|---|---|---|
| Mazda RX4 | 21.0 | 6 | 160 | 110 |
| Mazda RX4 Wag | 21.0 | 6 | 160 | 110 |
| Datsun 710 | 22.8 | 4 | 108 | 93 |
| Hornet 4 Drive | 21.4 | 6 | 258 | 110 |
| Hornet Sportabout | 18.7 | 8 | 360 | 175 |
O pacote sparkline
O sparkline é um pacote ótimo para enriquecer as apresentações de forma que possibilita incluir “mini gráficos” como boxplots, gráfico de linhas ou barras diretamente nas tabelas, como se fosse uma coluna do data.frame!
Seu funcionamento é bem simples e poderoso, apresento aqui alguns exemplo de uso, caso queira conferir mais detalhes, pode conferir o manual do pacote no CRAN ou esta página.
# library(devtools)
# install_github('htmlwidgets/sparkline')
#Carregando o pacote:
library(htmlwidgets)
library(sparkline)
#Exemplos de uso:
x = rnorm(20)
sparkline(x)
sparkline(x, type = 'bar')
sparkline(x, type = 'box')
Exemplo de tabela para rmarkdown, a partir dessa sequência de códigos markdown e R:
#Seja:
set.seed(1234)
x = rnorm(10)
y = rnorm(10)
#Ao digitar isso:
| Var. | Sparkline | Boxplot | Bar
|-------|-------------------|-------------------------------|------------------------------
| x | `r sparkline(x)` | `r sparkline(x, type ='box')` |`r sparkline(x, type = 'bar')`
| y | `r sparkline(y)` | `r sparkline(y, type ='box')` |`r sparkline(y, type = 'bar')`Exibe isso:

O pacote rhandsontable
Mais um pacote repleto de funcionalidades que permitem a implementação de tabelas elegantes para a apresentação de projetos e pesquisas. Por se tratar de um htmlwidgets, este pacote em especial é uma boa opção quando deseja-se apresentar tabela sem documentos no formato html ou com aplicativos shiny por exemplo.
Primeiramente apresentarei aqui primeiramente um exemplo com tabela de correlações utilizando formatação condicional:
#Carregando o pacote:
library(rhandsontable)
#Tabela para correlações
rhandsontable(cor(iris[,-5]), readOnly = TRUE, width = 750, height = 300) %>%
hot_cols(renderer = "
function (instance, td, row, col, prop, value, cellProperties) {
Handsontable.renderers.TextRenderer.apply(this, arguments);
if (row == col) {
td.style.background = 'lightgrey';
} else if (col > row) {
td.style.background = 'grey';
td.style.color = 'grey';
} else if (value < -0.75) {
td.style.background = 'pink';
} else if (value > 0.75) {
td.style.background = 'lightgreen';
}
}")
Como este pacote possui muitas funcionalidades, apresentarei mais três exemplos baseados nas instruções do pacote e caso queira entender melhor o funcionamento e obter mais exemplos, consultar o manual no CRAN
#Tabela com mini gráficos
#criando um data.frame
df <- data.frame(
id = 1:10,
Nomes = c("Sofia", "Kiara", "Dunki", "Edgar", "Aline","Gertrudes", "Genovena", "Champanhe", "Pérola", "Penelope"),
Kilos = accounting(c(20000, 30000, 50000, 70000, 47000,80000,45000,35000,20000,25000), format = "d"),
Crescimento = percent(c(0.1, 0.2, 0.5, 0.95, 0.97,0.45,0.62,0.57,0.37, 0.3), format = "d"),
Suficiente = c(T, F, T, F, T,F,F,T,T,F))
#E os gráficos de barra:
df$chart = c(sapply(1:5,
function(x) jsonlite::toJSON(list(values=rnorm(10,10,10),
options = list(type = "bar")))),
sapply(1:5,
function(x) jsonlite::toJSON(list(values=rnorm(10,10,10),
options = list(type = "line")))))
rhandsontable(df, rowHeaders = NULL, width = 550, height = 300) %>%
hot_col("chart", renderer = htmlwidgets::JS("renderSparkline"))
Também podemos incluir comentários em células específicas da tabela utilizando este pacote, veja:
(Para ver os comentários basta passar o mouse sobre a célula com a marcação vermelha na borda)
#Incluindo comentarios:
comments = matrix(ncol = ncol(df), nrow = nrow(df))
comments[1, 1] = "Exemplo de comentário"
comments[2, 2] = "Outro exemplo de comentario"
rhandsontable(df, comments = comments, width = 550, height = 300)%>%
hot_col("chart", renderer = htmlwidgets::JS("renderSparkline"))
Caso a tabela dos dados seja muito grande, também podemos utilizar o pacote para gerar a tabela com a barra de rolar
#Tabela com barra de rolar para grande base de dados
rhandsontable(mtcars, rowHeaderWidth = 200, width = 700, height = 550)Relatórios muito mais bonitos
Com essas lindas tabelas seus relatórios serão irresistíveis, até quem não entende de estatística vai passar a gostar depois de ver tanta beleza com números! Espero que tenha gostado do conteúdo, caso queira acrescentar ou reportar algo basta entrar em contato.
Se quiser conferir outros posts que passaram por aqui ao longo do ano, dá uma olhada na retrospectiva anual do blog.
Perguntas frequentes
Qual pacote usar para tabelas interativas no R?
Para tabelas interativas, o DT é a opção mais direta em relatórios HTML e o rhandsontable é ótimo quando você quer células editáveis, comentários ou uso em aplicativos Shiny. Ambos geram tabelas navegáveis sem que você precise escrever JavaScript.
Como adicionar cores ou barras nas células de uma tabela?
Use o formattable ou o kableExtra. Eles permitem formatação condicional: pintar o fundo por valor, colorir o texto, adicionar barras proporcionais e ícones. É o caminho para tabelas estáticas em PDF ou HTML com destaque visual nos números que importam.
Dá para colocar gráficos dentro de uma tabela?
Sim. O pacote sparkline insere mini gráficos (linha, barra ou boxplot) direto nas células, como se fossem uma coluna do data.frame. É uma forma compacta de mostrar tendência ou distribuição sem ocupar espaço com um gráfico separado.


