Insper 2022-33
Meu nome é Julio. Eu gosto de MasterChef
Eu não gosto de
Meu papel nessa disciplina será ajudar no aprendizado da parte técnica – códigos etc.
Nesse lab, nosso objetivo será construir soluções em R e python para problemas comuns de transformação de dados.
Equipes de 3 pessoas. Começaremos com uma alocação por afinidade. Dependendo dos resultados, realocamos.
Eu serei o Google. Na parte do R, verificarei se vocês fizeram tudo certo. Na parte do python, vocês vão me ensinar.
No final de cada exercício, discutiremos aspectos teóricos sobre as ferramentas (se necessário).
# A tibble: 344 × 8
especie ilha comprimento…¹ profu…² compr…³ massa…⁴ sexo ano
<fct> <fct> <dbl> <dbl> <int> <int> <fct> <int>
1 Pinguim-de-adélia Torgersen 39.1 18.7 181 3750 macho 2007
2 Pinguim-de-adélia Torgersen 39.5 17.4 186 3800 fêmea 2007
3 Pinguim-de-adélia Torgersen 40.3 18 195 3250 fêmea 2007
4 Pinguim-de-adélia Torgersen NA NA NA NA <NA> 2007
5 Pinguim-de-adélia Torgersen 36.7 19.3 193 3450 fêmea 2007
6 Pinguim-de-adélia Torgersen 39.3 20.6 190 3650 macho 2007
7 Pinguim-de-adélia Torgersen 38.9 17.8 181 3625 fêmea 2007
8 Pinguim-de-adélia Torgersen 39.2 19.6 195 4675 macho 2007
9 Pinguim-de-adélia Torgersen 34.1 18.1 193 3475 <NA> 2007
10 Pinguim-de-adélia Torgersen 42 20.2 190 4250 <NA> 2007
# … with 334 more rows, and abbreviated variable names ¹comprimento_bico,
# ²profundidade_bico, ³comprimento_nadadeira, ⁴massa_corporal
# ℹ Use `print(n = ...)` to see more rows
# A tibble: 3 × 4
especie media mediana diferenca
<fct> <dbl> <dbl> <dbl>
1 Pinguim-de-barbicha 48.8 49.6 0.716
2 Pinguim-gentoo 47.5 47.3 0.205
3 Pinguim-de-adélia 38.8 38.8 0.00861
# A tibble: 7,240 × 60
pais iso2 iso3 ano novos…¹ novos…² novos…³ novos…⁴ novos…⁵ novos…⁶
<chr> <chr> <chr> <int> <int> <int> <int> <int> <int> <int>
1 Afeganistão AF AFG 1980 NA NA NA NA NA NA
2 Afeganistão AF AFG 1981 NA NA NA NA NA NA
3 Afeganistão AF AFG 1982 NA NA NA NA NA NA
4 Afeganistão AF AFG 1983 NA NA NA NA NA NA
5 Afeganistão AF AFG 1984 NA NA NA NA NA NA
6 Afeganistão AF AFG 1985 NA NA NA NA NA NA
7 Afeganistão AF AFG 1986 NA NA NA NA NA NA
8 Afeganistão AF AFG 1987 NA NA NA NA NA NA
9 Afeganistão AF AFG 1988 NA NA NA NA NA NA
10 Afeganistão AF AFG 1989 NA NA NA NA NA NA
# … with 7,230 more rows, 50 more variables: novos_fpp_h65 <int>,
# novos_fpp_m014 <int>, novos_fpp_m1524 <int>, novos_fpp_m2534 <int>,
# novos_fpp_m3544 <int>, novos_fpp_m4554 <int>, novos_fpp_m5564 <int>,
# novos_fpp_m65 <int>, novos_fpn_h014 <int>, novos_fpn_h1524 <int>,
# novos_fpn_h2534 <int>, novos_fpn_h3544 <int>, novos_fpn_h4554 <int>,
# novos_fpn_h5564 <int>, novos_fpn_h65 <int>, novos_fpn_m014 <int>,
# novos_fpn_m1524 <int>, novos_fpn_m2534 <int>, novos_fpn_m3544 <int>, …
# ℹ Use `print(n = ...)` to see more rows, and `colnames()` to see all variable names
# A tibble: 3 × 6
pais `2008` `2009` `2010` `2011` `2012`
<chr> <int> <int> <int> <int> <int>
1 Brasil 37697 39212 37874 40253 40108
2 Índia 615492 624617 630164 642311 629589
3 Estados Unidos 4742 4010 3526 3686 3562
pais 2008 2009 2010 2011 2012
0 Brasil 37697 39212 37874 40253 40108
1 Índia 615492 624617 630164 642311 629589
2 Estados Unidos 4742 4010 3526 3686 3562
# A tibble: 26,115 × 15
origem ano mes dia hora tempe…¹ ponto…² umidade direc…³ veloc…⁴ veloc…⁵
<chr> <int> <int> <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 EWR 2013 1 1 1 39.0 26.1 59.4 270 10.4 NA
# … with 26,114 more rows, 4 more variables: precipitacao <dbl>, pressao <dbl>,
# visibilidade <dbl>, data_hora <dttm>, and abbreviated variable names
# ¹temperatura, ²ponto_condensacao, ³direcao_vento, ⁴velocidade_vento,
# ⁵velocidade_rajada
# ℹ Use `print(n = ...)` to see more rows, and `colnames()` to see all variable names
# A tibble: 1,458 × 8
codigo_aeroporto nome latit…¹ longi…² altura fuso_…³ horar…⁴ fuso_…⁵
<chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <chr>
1 04G Lansdowne Air… 41.1 -80.6 1044 -5 A Americ…
# … with 1,457 more rows, and abbreviated variable names ¹latitude, ²longitude,
# ³fuso_horario, ⁴horario_verao, ⁵fuso_horario_iana
# ℹ Use `print(n = ...)` to see more rows
# A tibble: 16 × 2
companhia_aerea nome
<chr> <chr>
1 9E Endeavor Air Inc.
# … with 15 more rows
# ℹ Use `print(n = ...)` to see more rows
# A tibble: 3,322 × 9
codigo_cauda ano tipo fabri…¹ modelo motores assen…² veloc…³ tipo_…⁴
<chr> <int> <chr> <chr> <chr> <int> <int> <int> <chr>
1 N10156 2004 Ala fixa mu… EMBRAER EMB-1… 2 55 NA Turbo …
# … with 3,321 more rows, and abbreviated variable names ¹fabricante,
# ²assentos, ³velocidade, ⁴tipo_motor
# ℹ Use `print(n = ...)` to see more rows
# A tibble: 336,776 × 19
ano mes dia horario_sa…¹ saida…² atras…³ horar…⁴ chega…⁵ atras…⁶ compa…⁷
<int> <int> <int> <int> <int> <dbl> <int> <int> <dbl> <chr>
1 2013 1 1 517 515 2 830 819 11 UA
# … with 336,775 more rows, 9 more variables: voo <int>, cauda <chr>,
# origem <chr>, destino <chr>, tempo_voo <dbl>, distancia <dbl>, hora <dbl>,
# minuto <dbl>, data_hora <dttm>, and abbreviated variable names
# ¹horario_saida, ²saida_programada, ³atraso_saida, ⁴horario_chegada,
# ⁵chegada_prevista, ⁶atraso_chegada, ⁷companhia_aerea
# ℹ Use `print(n = ...)` to see more rows, and `colnames()` to see all variable names
# A tibble: 10 × 5
fabricante nome origem n tempera…¹
<chr> <chr> <chr> <int> <dbl>
1 AIRBUS JetBlue Airways JFK 21003 54.8
2 EMBRAER JetBlue Airways JFK 16785 57.9
3 BOEING Delta Air Lines Inc. JFK 15474 57.2
4 BOMBARDIER INC Endeavor Air Inc. JFK 13844 55.6
5 AIRBUS INDUSTRIE Delta Air Lines Inc. LGA 8233 55.2
6 BOMBARDIER INC ExpressJet Airlines Inc. LGA 7573 60.5
7 MCDONNELL DOUGLAS AIRCRAFT CO Delta Air Lines Inc. LGA 6845 59.3
8 AIRBUS INDUSTRIE US Airways Inc. LGA 6280 57.1
9 BOEING Southwest Airlines Co. LGA 6072 57.3
10 BOEING American Airlines Inc. JFK 5146 56.3
# … with abbreviated variable name ¹temperatura_media
fabricante nome origem n \
0 AIRBUS JetBlue Airways JFK 21003
1 EMBRAER JetBlue Airways JFK 16785
2 BOEING Delta Air Lines Inc. JFK 15474
3 BOMBARDIER INC Endeavor Air Inc. JFK 13844
4 AIRBUS INDUSTRIE Delta Air Lines Inc. LGA 8233
5 BOMBARDIER INC ExpressJet Airlines Inc. LGA 7573
6 MCDONNELL DOUGLAS AIRCRAFT CO Delta Air Lines Inc. LGA 6845
7 AIRBUS INDUSTRIE US Airways Inc. LGA 6280
8 BOEING Southwest Airlines Co. LGA 6072
9 BOEING American Airlines Inc. JFK 5146
temperatura_media
0 54.811566
1 57.870006
2 57.198679
3 55.559239
4 55.164580
5 60.480547
6 59.313049
7 57.140805
8 57.276017
9 56.301159
voos_select <- voos |>
select(
ano, mes, dia, hora,
companhia_aerea, cauda,
origem, destino,
y = atraso_saida
) |>
drop_na(y)
voos_select
# A tibble: 328,521 × 9
ano mes dia hora companhia_aerea cauda origem destino y
<int> <int> <int> <dbl> <chr> <chr> <chr> <chr> <dbl>
1 2013 1 1 5 UA N14228 EWR IAH 2
2 2013 1 1 5 UA N24211 LGA IAH 4
3 2013 1 1 5 AA N619AA JFK MIA 2
4 2013 1 1 5 B6 N804JB JFK BQN -1
5 2013 1 1 6 DL N668DN LGA ATL -6
6 2013 1 1 5 UA N39463 EWR ORD -4
7 2013 1 1 6 B6 N516JB EWR FLL -5
8 2013 1 1 6 EV N829AS LGA IAD -3
9 2013 1 1 6 B6 N593JB JFK MCO -3
10 2013 1 1 6 AA N3ALAA LGA ORD -2
# … with 328,511 more rows
# ℹ Use `print(n = ...)` to see more rows
set.seed(1)
split <- rsample::initial_split(voos_select, prop = .8)
treino <- rsample::training(split)
teste <- rsample::testing(split)
feat_eng <- function(dados) {
# ...exercicio...
dados |>
select(-cauda)
}
treino_eng <- feat_eng(treino)
teste_eng <- feat_eng(teste) # cuidado
modelo <- parsnip::rand_forest("regression", trees = 20) |>
parsnip::set_engine("ranger")
fitted <- parsnip::fit(modelo, y ~ ., data = treino_eng)
preds <- predict(fitted, new_data = teste_eng)
result_antes <- yardstick::rmse_vec(teste_eng$y, preds$.pred)
Resultado antes:
[1] 36.98851
Resultado depois:
[1] 35.95097
Nesse lab, nosso objetivo será construir soluções em ggplot2 para gráficos estatísticos.
Os grupos são os que montamos para o trabalho final.
As tarefas serão imitar um gráfico que eu montei para vocês usando ggplot2. Eu mostrarei apenas a imagem. Posso dar dicas no meio do caminho.
O grupo que conseguir fazer o gráfico primeiro ganhará prêmios.
Quem fizer versões em python dos gráficos para me ensinar ganhará prêmios.
Utilizaremos a base de dados da olist, para que vocês possam aproveitar os trabalhos nas atividades integradoras.
Teoricamente, vocês já têm uma base de dados arrumada em mãos, por conta dos exercícios do curso de Design.
Para garantir que as visualizações funcionam, no entanto, disponibilizei uma base que eu montei (pode conter erros) no material dos labs.
A base está tanto em .parquet
(usar pacote {arrow}
quanto em .rds
. Use a que for mais confortável.
Se quiser usar sua própria base, sem problemas!
Usar a coluna types
Estudar a função theme()
As geom_label()
ficam na metade da altura da barra.
#' Author:
#' Subject:
# Import -----------------------------------------------------------------------
# readr::write_rds(d, "")
library(ggplot2)
# grafico 1 ---------------------------------------------------------------
items |>
dplyr::count(types) |>
dplyr::mutate(types = forcats::fct_reorder(types, n)) |>
dplyr::filter(n > 100) |>
dplyr::mutate(n = n/1000) |>
ggplot(aes(x = n, y = types)) +
geom_col(fill = "#8ae3d7", width = .5) +
geom_label(aes(label = round(n, 2), x = n/2)) +
theme_dark(16) +
labs(
x = "Quantidade\n(milhares)",
y = "Forma de pagamento",
title = "Formas de pagamento mais comuns",
subtitle = "Considerando tipos com mais de 100 observações",
caption = "Fonte: Olist"
) +
theme(
panel.background = element_rect(fill = "gray20"),
plot.background = element_rect(fill = "gray10"),
text = element_text(family = "serif", colour = "white"),
axis.text = element_text(family = "serif", colour = "white"),
panel.grid.minor = element_blank()
)
# grafico 2 ---------------------------------------------------------------
items |>
dplyr::mutate(
data = as.Date(order_purchase_timestamp),
data = lubridate::floor_date(data, "month"),
estado = forcats::fct_other(
seller_state,
keep = c("SP", "RJ"),
other_level = "Outros"
)
) |>
dplyr::filter(
data >= "2017-01-01",
data <= "2018-07-01"
) |>
dplyr::count(data, estado) |>
ggplot() +
aes(x = data, y = n, colour = estado) +
geom_line(size = 2) +
scale_color_viridis_d(begin = .2, end = .8) +
labs(
x = "Data",
y = "Quantidade",
title = "São Paulo tem mais vendas",
subtitle = "O que é esperado, pois a população é maior 😬",
caption = "Fonte: Olist",
color = "Estado"
) +
scale_x_date(
date_breaks = "3 month",
date_labels = "%b\n%Y"
) +
theme_light(15) +
theme(
legend.position = "bottom"
)
# grafico 04 --------------------------------------------------------------
estados <- geobr::read_state()
set.seed(42)
items |>
dplyr::count(
seller_state,
geolocation_lat_seller,
geolocation_lng_seller,
geolocation_lat_customer,
geolocation_lng_customer
) |>
dplyr::filter(seller_state %in% c("SP", "MG", "RJ")) |>
dplyr::slice_sample(n = 1000) |>
ggplot() +
geom_sf(data = estados, fill = "gray95", size = .1) +
geom_curve(
mapping = aes(
x = geolocation_lng_seller,
y = geolocation_lat_seller,
xend = geolocation_lng_customer,
yend = geolocation_lat_customer
),
arrow = arrow(length = unit(0.1, "inches")),
curvature = .2,
alpha = .2,
colour = "royalblue"
) +
facet_wrap(~seller_state, strip.position = "bottom") +
theme_void(base_size = 16) +
labs(
title = "Para onde vão as compras?",
subtitle = "Comparando São Paulo, Minas Gerais e Rio de Janeiro",
caption = "Fonte: Olist"
)
Usar scale_x_date()
Estudar scale_color_viridis_d()
lubridate::floor_date()
para aproximar datas
case_when()
ou fct_other()
para reclassificar uma variável categórica
filtrar a base para o intervalo de datas entre “2017-01-01” e “2018-07-01”
devemos contar/agrupar por data
(mês) e estado
items |>
dplyr::mutate(
data = as.Date(order_purchase_timestamp),
data = lubridate::floor_date(data, "month"),
estado = forcats::fct_other(
seller_state,
keep = c("SP", "RJ"),
other_level = "Outros"
)
) |>
dplyr::filter(
data >= "2017-01-01",
data <= "2018-07-01"
) |>
dplyr::count(data, estado) |>
ggplot() +
aes(x = data, y = n, colour = estado) +
geom_line(size = 2) +
scale_color_viridis_d(begin = .2, end = .8) +
labs(
x = "Data",
y = "Quantidade",
title = "São Paulo tem mais vendas",
subtitle = "O que é esperado, pois a população é maior 😬",
caption = "Fonte: Olist",
color = "Estado"
) +
scale_x_date(
date_breaks = "3 month",
date_labels = "%b\n%Y"
) +
theme_light(15) +
theme(
legend.position = "bottom"
)
Usar o pacote {ggridges}
.
Para pintar apenas uma categoria, crie uma coluna.
Para anotações no gráfico (como “Mediana”), use a função annotate()
.
Para fazer os reais, use a função scales::scales_dollar_format()
.
items_agg <- items |>
group_by(product_category_name) |>
filter(n() > 4000) |>
ungroup() |>
mutate(
product_category_name = fct_reorder(
product_category_name, price, median
),
relogios = ifelse(
product_category_name == "relogios_presentes",
"destacar", "não destacar"
)
)
mediana <- items_agg |>
summarise(mediana = median(price))
items_agg |>
ggplot() +
aes(x = price, y = product_category_name, fill = relogios) +
ggridges::geom_density_ridges(
quantile_lines = TRUE,
quantiles = 2,
na.rm = FALSE,
n = 2048,
show.legend = FALSE
) +
scale_x_continuous(
limits = c(0, NA),
labels = scales::dollar_format(prefix = "R$")
) +
coord_cartesian(xlim = c(0, 300)) +
geom_vline(
aes(xintercept = mediana),
data = mediana,
linetype = 2,
colour = "red"
) +
scale_fill_manual(
values = c("#6686e6", "#eaeaea")
) +
theme_minimal()
Faça uma amostra de 1000 observações dos dados, com set.seed(42)
Para obter o mapa, usar o pacote {geobr}
Para plotar o mapa, usar a função geom_sf()
Estamos desenhando CURVAS
Use facets
estados <- geobr::read_state()
set.seed(42)
items |>
dplyr::count(
seller_state,
geolocation_lat_seller,
geolocation_lng_seller,
geolocation_lat_customer,
geolocation_lng_customer
) |>
dplyr::filter(seller_state %in% c("SP", "MG", "RJ")) |>
dplyr::slice_sample(n = 1000) |>
ggplot() +
geom_sf(data = estados, fill = "gray95", size = .1) +
geom_curve(
mapping = aes(
x = geolocation_lng_seller,
y = geolocation_lat_seller,
xend = geolocation_lng_customer,
yend = geolocation_lat_customer
),
arrow = arrow(length = unit(0.1, "inches")),
curvature = .2,
alpha = .2,
colour = "royalblue"
) +
facet_wrap(~seller_state, strip.position = "bottom") +
theme_void(base_size = 16) +
labs(
title = "Para onde vão as compras?",
subtitle = "Comparando São Paulo, Minas Gerais e Rio de Janeiro",
caption = "Fonte: Olist"
)
O pacote flexdashboard
oferece um layout de R Markdown para construir dashboards estáticos diretamente do R.
Um dashboard estático é aquele que não exige um servidor com uma sessão de R rodando por trás. Dashboards gerados com flexdashboard
são apenas um arquivo .html
, que pode ser enviado para qualquer usuário e tudo o que ele precisará para abrir o arquivo é um navegador (Firefox, Chrome etc), isto é, ele não precisará do R ou RStudio instalado na máquina dele para visualizar o seu trabalho.
Por usar RMarkdown, tudo o que precisaremos aprender para construir um flexdashboard é qual marcação deveremos usar para construir cada elemento do dashboard.
Shiny é um framework em linguagem R para a criação de aplicativos web. Por não exigir conhecimento prévio de HTML, CSS e JavaScript, ele democratiza o acesso a essa área de desenvolvimento, permitindo a criação de aplicativos bonitos e complexos a partir de um script R.
Um aplicativo Shiny pode ser reduzido a vários elementos:
uma página web: ele será acessado por um navegador, possuirá um endereço (URL) e será constituído por HTML, CSS e JavaScript.
um aplicativo web: permitirá que quem estiver acessando intereja com as visualizações apresentadas.
um código (ou uma coleção de códigos) em linguagem R: construídos, sobretudo, com o pacote {shiny}
.
Por ser estático, o flexdashboard permite o compartilhamento dos resultados como arquivo, podendo ser passado como anexo. No entanto, ele tem limitações na customização e em poder computacional.
O flexdashboard é indicado para apresentações.
Já o shiny é muito mais robusto e completo, permitindo fazer quaisquer interações entre o R e a web. É mais difícil de programar e precisa de um servidor na nuvem para rodar. O deploy é bem fácil, mas necessário.
O flexdashboard é indicado para produtos.
Conta ainda com uma versão “shinylive”, permitindo rodar shiny diretamente do navegador 🤩
Um aplicativo Shiny tem dois componentes básicos: a interface de usuário e o servidor.
Construção do código HTML que compõe o app. Podemos pensar na programação desse código HTML como a construção daquilo que será mostrado na tela, a cara do seu app, a interface de usuário ou UI (sigla para o termo user interface, em inglês).
Coisas que não serão vistas por quem utilizar o app: o servidor. O lado do servidor (server side ou simplesmente server, em inglês) contém toda a lógica para a construção das saídas apresentadas na UI.
A figura a seguir mostra a UI de um app bem simples, que permite a escolha de duas variáveis e apresenta o gráfico de dispersão delas:
Embora precisemos aprender alguns conceitos e regras novas, a maior parte do código que compõe o servidor é aquele bom e velho R que já utilizamos no dia-a-dia para gerar tabelas, gráficos e qualquer outro tipo de visualização.
Em resumo, para fazer um ggplot aparecer no Shiny, basta adaptar o código que gera esse gráfico para receber as entradas de quem estiver usando o app (inputs) e devolver o resultado (output) no lugar adequado.
O código de qualquer aplicativo em Shiny terá a estrutura abaixo:
Um objeto chamado ui
.
Uma função chamada server
.
Uma chamada da função shinyApp()
.
No objeto ui
, construímos o que será mostrado na tela para o usuário. Nele, devemos:
Construir o layout do aplicativo.
Definir quais visualizações serão mostradas (tabelas, gráficos, mapas etc).
Definir elementos de CSS e JavaScript. [avançado]
Todas as funções que utilizarmos para criar o ui
retornarão código HTML. O objeto ui
, portanto, será um grande código HTML.
Neste contexto, serão sinônimos: UI, interface de usuário, front-end, front.
Se você não conhece essas linguagens, uma boa maneira de entender o papel de cada uma delas na construção de um site é pensar em uma casa.
Podemos pensar o HTML como a estrutura física da casa: chão, paredes, colunas, teto, encanamento, fiação etc.
O CSS é o responsável pela aparência: pintura, pisos, azulejos, decoração em geral.
O JavaScript traz funcionalidades a cada cômodo: pia, vaso sanitário, geladeira, cama, televisão e por aí vai.
Com o Shiny, podemos produzir aplicativos web em HTML, CSS e JavaScript sem saber programar nessas linguagens. E melhor: sem sair do R!
A função server()
vai receber nossos usuais códigos R de manipular bases, gerar tabelas, gráficos, mapas e qualquer outra visualização que quisermos construir.
A função server()
sempre terá os parâmetros:
input
: uma lista com todos parâmetros que o usuário pode mexer.
output
: uma lista com todas as visualizações que vamos mostrar para o usuário.
session
: uma lista com informações da sessão que está rodando o aplicativo.
Neste contexto, serão sinônimos: server, servidor, back-end.
Enquanto estamos desenvolvendo um aplicativo Shiny, queremos testá-lo localmente para verificar se tudo funciona corretamente.
Testar localmente significa que o seu próprio computador fará as vezes de servidor, embora isso não signifique que seu app ficará disponível na internet.
No RStudio, podemos rodar nossos apps:
rodando o script que contém o nosso app;
clicando no botão Run App;
rodando no console a função runApp("caminho/ate/app.R)
.
Ao clicar nesse botão, o seu navegador padrão será aberto e você verá a UI do nosso modesto app com apenas a frase “Olá, mundo!”.
Se você voltar ao RStudio, eventualmente vai notar algo muito importante: a sua sessão de R estará ocupada! Isso acontece porque todo Shiny app precisa de uma sessão de R rodando por trás.
Essa sessão fornece a comunicação da UI (ou do nosso navegador) com o servidor e é responsável por atualizar as visualizações apresentadas na UI, sempre que alguém interagir com o app. Embora o nosso app Olá, mundo não possuir interatividade, a estrutura necessária para que a interatividade aconteça ainda assim é criada pelo Shiny.
Para liberar a sessão, basta clicar no botão “stop”, na parte de cima do Console, ou pressionar a tecla Esc
. Veja que, ao fazer isso, a tela do app ficará acizentada, indicando que ele foi desconectado do servidor e não funcionará mais corretamente.
Repare que a mensagem no Console representa o endereço do nosso aplicativo. Nesse caso, será um IP (http://127.0.0.1
) com alguma porta que esteja disponível escolhida aleatoriamente (:4028
). Esse endereço aparecerá no nosso navegador e poderemos copiá-lo e colá-lo em qualquer outra aba ou navegador que quisermos rodar o app.
Vamos criar e rodar o exemplo minimal do slide anterior.
Ao RStudio: 01-ola-mundo.R
Uma das principais tarefas no desenvolvimento de um Shiny app é a definição e construção dos inputs e outputs. São esses elementos que nos permitem interagir com o app.
Outputs representam as saídas do nosso aplicativo, isto é, tudo que queremos que nosso código R retorne para o usuário. Essas saídas podem ser tabelas, gráficos, mapas, texto, imagens ou qualquer outro elemento em HTML.
Os outputs são definidos na UI e criados no server. Cada tipo de output é definido por uma função do tipo *Output()
. Veja as principais funções dessa família:
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()
.
Veja a seguir as principais funções render*()
e como elas se comunicam com as funções *Output()
.
O argumento outputId
das funções _Output()
é utilizado para nos referirmos aos outputs dentro do server. Todos os outputs criados ficarão dentro da lista output
.
No código do slide anterior:
a função plotOutput()
especifica o lugar na UI será colocado o histograma (no caso, logo abaixo do texto "Histograma da variável mpg"
);
para criar o histograma, atribuímos o resultado da função renderPlot()
ao valor histograma
da lista output
, mesmo nome dado ao argumento outputId
na função plotOutput()
;
a função renderPlot()
, assim com qualquer outra função da família render*()
, recebe como primeiro argumento o código para gerar o output;
o histograma é gerado com o código hist(mtcars$mpg)
.
Vamos criar e rodar um shiny app com um gráfico como output.
02-output.R
Inputs representam as entradas do nosso aplicativo, isto é, a maneira como informações são transmitidas entre a pessoa usando o app e o servidor. Essas informações podem ser valores, textos, datas, arquivos ou até mesmo cliques em um botão.
Para facilitar a escolha desses valores, o pacote shiny
possibilita diversas opções de widgets, a depender do tipo de valor a ser passado.
Você pode conferir a lista de widgets do pacote shiny
nesta página. Repare que no campo Current Value(s)
é mostrado qual valor será levado para dentro da função server
em cada caso.
Para criar esses widgets utilizamos as famílias de funções *Input()
ou *Button
.
De forma análoga ao outputId
das funções *Output()
, todas essas funções possuem inputId
como primeiro argumento, que recebe uma string e será utilizado para acessar cada input dentro da função server
.
Isso implica que dois inputs não podem ter o mesmo inputId
. Apenas o primeiro input funcionará caso você crie dois ou mais inputId
repetidos.
Para acessar os inputs dentro da função server, utilizamos a lista input
. Essa lista guardará todos os inputs criados no UI.
- input$num
pode ser usado no server para deixar as visualizações dinâmicas.
Colocar um seletor de variáveis para permitir que o usuário escolha a variável exibida no histograma.
03-output-input.R
Vamos fazer um app com dois pares input/output independentes.
04-dois-inputs-outputs.R
O shinyapps.io é um serviço do RStudio para hospedagem de Shiny apps.
A conta gratuita permite você ter até 5 aplicações e 25 horas mensais de uso (um aplicativo utilizado por 1 hora consome 1 hora do seu plano, 2 aplicativos utilizados simultaneamente por 1 hora consomem 2 horas do seu plano).
Criada uma conta, você poderá subir o seu app para o shinyapps.io diretamente do RStudio. Para isso, você precisará apenas conectar a sua conta com o RStudio.
Neste vídeo, mostramos como conectar o shinyapps.io com o RStudio.
Vamos conectar o nosso RStudio com o shinyapps.io e subir um app para lá.
Ao RStudio: 04-dois-inputs-outputs.R
2022