All Posts By

Vitor Ostrensky

Dados do comércio internacional no R

By | Data Science, Economia

A base de dados UN Comtrade fornece acesso gratuito às informações de comércio global. É possível obter dados usando sua interface de extração ou API. Por sorte, existe um pacote chamado comtradr que facilita o uso da API no R. Neste post, iremos mostrar um pouco da funcionalidade dele.

 

 
library(comtradr)
library(tidyverse)
library(splitstackshape)
library(inlmisc)

Primeiramente, iremos selecionar os dados de exportações brasileiras com quatro países: China, Estados Unidos, Argentina e Holanda. Como não selecionamos o período, todos os dados desde 1990 são retornados. Além disso, é possível filtrar por tipo de produto. Neste caso, estamos selecionando o total exportado.

 

 
braziltop <- ct_search(reporters = "Brazil", 
partners = c("USA", "China", "Argentina", "Netherlands"), 
trade_direction = "exports") %>%
ct_use_pretty_cols()

Veja que o formato de saída torna muito simples fazer um gráfico com a evolução das exportações ao longo dos anos. Fica evidente a rápida expensão chinesa para se tornar principal destino dos produtos brasileiros.

 

 
ggplot(braziltop, aes(Year, `Trade Value usd`, color = factor(`Partner Country`))) +
geom_point(size = 2) +
geom_line(size = 1) +
scale_color_manual(values = c("#011627", "#FF3366", "#2EC4B6", "#20A4F3"), 
name = "País") +
scale_shape_discrete(name = "País") +
labs(title = "Destino das exportações brasileiras",
y = "Total em dólares",
x = "Ano") +
theme_minimal()

Agora, ao invés de selecionarmos todos os produtos, iremos escolher apenas as exportações de peixe. Para fazer a filtragem, é preciso utilizar os códigos do sistema harmonizado (SH), que cataloga os produtos em categorias gerais e específicas. Essa filtragem é feita no parâmetro "commod_codes" da função. Iremos extrair apenas os dados referentes a 2020.

Como nós selecionamos os produtos, a API retorna o dado individual de cada categoria. Assim, iremos somar o valor exportado por país de destino.

export_peixe <- ct_search(reporters = "Brazil", 
partners = "All", 
trade_direction = "exports",
start_date = 2020, 
end_date = 2020,
commod_codes = c("0301","0302","0303","0304","0305")
) %>%
ct_use_pretty_cols() %>%
group_by(`Partner Country`) %>%
summarise("Total" = sum(`Trade Value usd`)) %>%
filter(`Partner Country` != "World")

A partir destes dados, iremos criar um gráfico que mostre a composição relativa de cada país. Para isso, é preciso antes fazer algumas alterações na formatação dos dados, de modo que o dataframe final tenha a o número de quadrantes ocupado por cada país e suas posições.

</pre>
export_peixe$prop = 100*export_peixe$Total/sum(export_peixe$Total)
export_peixe = expandRows(export_peixe, "prop")
export_peixe <- rbind(export_peixe,
export_peixe[sample(nrow(export_peixe), 100- nrow(export_peixe)), ])

var = export_peixe$`Partner Country`
nrows <- 10
categ_table <- round(table(var) * ((nrows*nrows)/(length(var))))

base <- expand.grid(y = 1:nrows, x = 1:nrows)
base$category <- factor(rep(names(categ_table), categ_table))

ggplot(base, aes(x = x, y = y, fill = category)) +
geom_tile(color = "black", size = 0.5) +
scale_fill_manual(values = as.character(GetColors(n = 9,
scheme = "roma",
alpha = 0.9))) +
theme_void() +
labs(title = "Destino das exportações de Peixe pelo Brasil (2020)") +
scale_x_continuous(expand = c(0, 0)) +
scale_y_continuous(expand = c(0, 0), trans = 'reverse') +
theme(panel.border = element_rect(size = 2, fill = NA))
<pre>
 

 

 

Com isso, vemos uma predominância dos Estados Unidos como destino das exportações brasileiras de peixe.

Pirâmide etária da vacinação

By | Notas

A vacinação tem avançado de forma acelerada no país. Em muitos regiões, já estamos vacinando as pessoas na casa dos 30 anos. Apesar disso, ainda deve levar algum tempo até uma parcela considerável da população estar plenamente imunizada.

Inspirado em um tweet que vi a algum tempo, resolvi replicar essa visualização bastante interessante, que mostra a quantidade de vacinados em relação à população por meio de uma pirâmide etária.

Como os microdados da vacinação para todo o país geram um arquivo muito grande, optei por selecionar apenas dos dados do Paraná. Os dados de vacinação estão disponíveis aqui. Seguindo o código abaixo, é possível construir o mesmo gráfico para qualquer um dos estados.


library(tidyverse)
library(sidrar)

dados = read.csv2("vacina_PR.csv")

Os dados de população serão obtidos por meio da PNAD contínua anual de 2019, com o pacote *sidrar*. Para o gráfico ficar no formato de pirâmide, iremos alterar o valor das mulheres para ser negativo.

piramide = get_sidra(6706, 
variable = 606, 
geo = "State",
geo.filter = list("State" = 41)) %>%
filter(Sexo != "Total") %>%
mutate(`Grupo de idade` = ifelse(`Grupo de idade` == "5 a 9 anos",
"05 a 9 anos",
`Grupo de idade`),
Valor = ifelse(Sexo == "Mulheres",-Valor, Valor))

 

Primeiramente, iremos selecionar apenas as primeiras doses. A mesma visualização pode ser feita para a segunda dose, alterando essa linha. Como os dados de população estão disponíveis por faixas de renda, iremos colocar os dados de vacinação nestas faixas. Assim, agrupamos por faixa de idade e gênero para contar as pessoas. Da mesma forma que fizemos para a população, também iremos tornar a quantidade de mulheres negativa.


dados_g = dados %>%
filter(str_replace_all(vacina_descricao_dose, "[^[:alnum:]]", " ") == "1ª Dose") %>%
mutate(`Grupo de idade` = case_when(paciente_idade < 5 ~ "0 a 4 anos",
paciente_idade > 4 & paciente_idade < 10 ~ "05 a 9 anos",
paciente_idade > 9 & paciente_idade < 15 ~ "10 a 14 anos",
paciente_idade > 14 & paciente_idade < 20 ~ "15 a 19 anos",
paciente_idade > 19 & paciente_idade < 25 ~ "20 a 24 anos",
paciente_idade > 24 & paciente_idade < 30 ~ "25 a 29 anos",
paciente_idade > 29 & paciente_idade < 35 ~ "30 a 34 anos",
paciente_idade > 34 & paciente_idade < 40 ~ "35 a 39 anos",
paciente_idade > 39 & paciente_idade < 45 ~ "40 a 44 anos",
paciente_idade > 44 & paciente_idade < 50 ~ "45 a 49 anos",
paciente_idade > 49 & paciente_idade < 55 ~ "50 a 54 anos",
paciente_idade > 54 & paciente_idade < 60 ~ "55 a 59 anos",
paciente_idade > 59 & paciente_idade < 65 ~ "60 a 64 anos",
paciente_idade > 64 & paciente_idade < 70 ~ "65 a 69 anos",
paciente_idade > 69 & paciente_idade < 75 ~ "70 a 74 anos",
paciente_idade > 74 & paciente_idade < 80 ~ "75 a 79 anos",
paciente_idade > 79 ~ "80 anos ou mais")) %>%
group_by(`Grupo de idade`, paciente_enumsexobiologico) %>%
tally() %>%
filter(paciente_enumsexobiologico %in% c("M", "F")) %>%
mutate(n = ifelse(paciente_enumsexobiologico == "F", -n, n),
paciente_enumsexobiologico = ifelse(paciente_enumsexobiologico == "F",
"Mulheres",
"Homens"))

Assim, basta fazer o gráfico de pirâmide etária com dois "geom_bar". O primeiro é o de população, que fica no fundo. Já o segundo é o de dados da vacinação.

ggplot() +
geom_bar(data=piramide, 
aes(y=Valor*1000, x = `Grupo de idade`, fill = Sexo), 
stat="identity", alpha = 0.4, width=1) +
geom_bar(data=dados_g, 
aes(y=n, x = `Grupo de idade`, fill = paciente_enumsexobiologico),
stat="identity", width=1) +
scale_fill_manual(values = c("#c23c3c", "#276f9c", "#276f9c", "#c23c3c")) +
coord_flip() +
theme_classic() +
ggtitle("Pirâmide etária de vacinados com a primeira dose no Paraná",
subtitle="Com dados do dia 14/07/2021") +
scale_y_continuous(labels = abs) +
ylab("Número de pessoas") 

 

Analisando a despesa com energia elétrica por faixa de renda

By | Data Science, Economia

Como já mencionado no comentário de conjuntura desta semana, a crise hídrica tem levado a um aumento do risco de desabastecimento energético no país. Os efeitos econômicos disso podem ser bastante graves, dado que o aumento da tarifa pode fortalecer a alta da inflação. Já uma piora do cenário poderia levar a um racionamento, como em 2001, impactando diretamente na recuperação econômica atual.

Além disso, um impacto menos comentado do aumento do preço da energia é o efeito distributivo.  O gasto com energia ocupa muito mais espaço no orçamento das pessoas com renda mais baixa. Assim, aumentos tendem a ser mais danosos a essa parte da população. Podemos ver isso utilizando os dados da Pesquisa de Orçamentos Familiares (POF-17/18) do IBGE.

Para extrair os dados, utilizaremos o pacote {sidrar}. Além do gasto com energia, também selecionamos alguns outros tipos de despesa, para comparação.


library(tidyverse)
library(sidrar)

pof = get_sidra(6715, 
period = "all", 
variable = 1204, 
classific = c("C12190","C339"), 
category = list(c(8018,103561,103574,
103585,103618, 103539), 
c(47558, 47559,47560,
47561,47562,47563,
47564))) %>%
mutate(`Tipos de despesa` = gsub("[[:punct:]]|[[:digit:]]", "", `Tipos de despesa`)) %>%
rename("classes" = `Classes de rendimento total e variação patrimonial mensal familiar`)

Assim, podemos construir o gráfico com a porcentagem de gastos com eletricidade pelo total de despesas.

 


ggplot(subset(pof, pof$`Tipos de despesa` == "Energia elétrica"),
mapping = aes(x = factor(classes,
levels=c("Até 1.908 Reais", 
"Mais de 1.908 a 2.862 Reais", 
"Mais de 2.862 a 5.724 Reais", 
"Mais de 5.724 a 9.540 Reais", 
"Mais de 9.540 a 14.310 Reais", 
"Mais de 14.310 a 23.850 Reais",
"Mais de 23.850 Reais")),
y = Valor,
fill = factor(classes,
levels=c("Até 1.908 Reais", 
"Mais de 1.908 a 2.862 Reais", 
"Mais de 2.862 a 5.724 Reais", 
"Mais de 5.724 a 9.540 Reais", 
"Mais de 9.540 a 14.310 Reais", 
"Mais de 14.310 a 23.850 Reais",
"Mais de 23.850 Reais")))) + 
geom_bar(stat='identity',
position="dodge") +
labs(fill="Faixa de renda") +
theme_minimal() +
scale_fill_brewer(palette = "RdBu") +
ylab("Porcentagem da despesa total") +
geom_text(aes(x = classes, label=Valor), vjust=-0.5, color="black", size=5) +
ggtitle("Despesa com eletricidade por faixa de renda") +
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank())

Portanto, para famílias com renda de até 1.908 reais, o gasto com energia elétrica corresponde a 4.4% da despesa total. Já para famílias com mais de 23.850 reais de renda, esse valor corresponde a apenas 0.9%.

Além disso, iremos plotar o mesmo gráfico com os seguintes tipos de despesa: Alimentação, Saúde, Aumento do ativo (investimentos), Educação e Transporte.


ggplot(subset(pof, pof$`Tipos de despesa` != "Energia elétrica"),
mapping = aes(x = `Tipos de despesa`,
y = Valor,
fill = factor(classes,
levels=c("Até 1.908 Reais", 
"Mais de 1.908 a 2.862 Reais", 
"Mais de 2.862 a 5.724 Reais", 
"Mais de 5.724 a 9.540 Reais", 
"Mais de 9.540 a 14.310 Reais", 
"Mais de 14.310 a 23.850 Reais",
"Mais de 23.850 Reais")))) + 
geom_bar(stat='identity',
position="dodge") +
labs(fill="Faixa de renda") +
theme_minimal() +
scale_fill_brewer(palette = "RdBu") +
ylab("Porcentagem da despesa total") +
ggtitle("Despesa com outras categorias por faixa de renda")

Este gráfico mostra que o mesmo padrão ocorre para os gastos com alimentação. Entretanto, como o esperado, investimentos, educação e transporte apresentam a relação inversa.

 

Analisando dados do Spotify no R

By | Hackeando o R

Todo ano os cientistas de dados do Spotify criam uma retrospectiva musical dos seus usuários. Essa apresentação é compartilhada por muitas pessoas nas redes sociais, que debatem acerca das suas preferências. A plataforma permite o acesso a alguns destes dados por meio de uma API. Para acessa-la com facilidade, podemos utilizar o pacote {spotifyr}.

Primeiramente, deve ser feito um cadastro no site do Spotify (https://developer.spotify.com/). Assim, podemos obter a chave pessoal para acessar a API. Basta colocar o ID e essa chave da seguinte maneira:

library(tidyverse)
library(spotifyr)
library(ggridges)

Sys.setenv(SPOTIFY_CLIENT_ID = 'xxxxxxxx')
Sys.setenv(SPOTIFY_CLIENT_SECRET = 'xxxxxxx')

access_token <- get_spotify_access_token()

Existem várias funções diferentes que podemos fazer neste pacote. Podemos obter características sonoras, datas de lançamento, popularidade, entre outras coisas. É possível também obter seus próprios dados de consumo. Por exemplo, a função "get_my_saved_albuns", retorna todos os álbuns das músicas que você curtiu. Esta função possui um limite de 50 álbuns, assim como outras semelhantes. Assim é preciso utilizar um loop para obter todos os seus álbuns.

No caso, selecionei os meus álbuns com as variáveis de data de lançamento e popularidade. Com esta categoria, criei uma variável binária para separar os álbuns entre populares e não-populares, utilizando um limite de 50 na escala do aplicativo.

lista = list()

for (i in seq(0,10)){
  x = i*50

  lista[[i+1]] <- get_my_saved_albums(limit = 50, offset = x)

  if (nrow(lista[[i+1]]) < 50){
  break
  }
}

meus_albuns <- bind_rows(lista, .id = "column_label") %>%
select(album.artists, album.name, album.popularity, album.release_date) %>%
mutate(album.release_date = stringr::str_extract(album.release_date, "^.{4}")) %>%
mutate(faixa_popularidade = ifelse(album.popularity > 50,"Populares", "Não-Populares"))

Assim, é possível criar um gráfico para observar o seu gosto em relação aos anos de lançamento.

 


ggplot(meus_albuns) +
geom_histogram(aes(x = album.release_date, fill = faixa_popularidade),stat="count", alpha = 0.8) +
theme_minimal() +
scale_x_discrete(breaks=seq(1969, 2020, 5)) +
scale_fill_brewer(palette = "Dark2") +
ylab("Álbuns na playlist") +
xlab("Ano de lançamento")

 

Outra possibilidade interessante é extrair informações de bandas ou gêneros específicos. Podemos, por exemplo, selecionar a banda Pearl Jam para analisar alguma característica sonora do conjunto. Um dado interessante é observar a chamada "valência" das músicas. Basicamente, a valência descreve a positividade musical de uma canção. Músicas com valência mais altas soam mais positivas.

Assim, selecionamos os álbuns de estúdio da banda para acompanhar a distribuição das músicas pela valência, que parece aumentar ao longo dos anos.

 


PJ <- get_artist_audio_features('Pearl Jam') %>%
mutate(ano_album = paste0(album_release_year, " - ", album_name)) %>%
filter(album_name %in% c("Ten", "Vs.", "Vitalogy", "No Code",
"Yield", "Binaural", "Riot Act",
"Pearl Jam", "Backspacer", "Lightning Bolt",
"Gigaton"))

ggplot(PJ, aes(x = valence, y = ano_album, fill = ano_album)) +
geom_density_ridges(alpha = 0.5, jittered_points = TRUE) +
theme_ridges() +
guides(fill=FALSE,color=FALSE) +
ggtitle("Valência dos álbuns do Pearl Jam")

 

Novo operador pipe do R

By | Data Science, Hackeando o R

Lançada em Maio, a versão 4.1 do R trouxe algumas novidades para os usuários, como uma nova sintaxe de função anônima e uma nova engine gráfica. Entretanto, a mudança mais substancial foi a inclusão de um operador pipe nativo, o "|>". Para quem, como eu, está acostumado a utilizar o operador "%>%" do pacote magritt/tidyverse, a forma de utilização é bastante semelhante. Lembrando que operador pipe tem a função de permitir o encadeamento de uma função após a outra sem precisar criar variáveis intermediárias ou utilizar parênteses intermináveis.

A utilidade principal do pipe é melhorar a leitura do código. Por exemplo, todos as maneiras abaixo retornam o mesmo resultado.

#Variáveis intermediárias
mtcars_filt = filter(mtcars, drat > 3)
mtcars_group = group_by(mtcars_filt, gear)
mtcars_final = summarise(mtcars_group, hp = mean(hp))

#Utilizando parênteses

mtcars_final = summarise(group_by(filter(mtcars, drat > 3), gear), hp = mean(hp))

#Pipe

mtcars_final = mtcars %>%
filter(drat > 3) %>%
group_by(gear) %>%
summarise(hp = mean(hp))

Para utilizar o novo pipe, a sintaxe é exatamente a mesma, nesse caso.

#Novo pipe

mtcars_final = mtcars |>
filter(drat > 3) |>
group_by(gear) |>
summarise(hp = mean(hp))
<pre>

A vantagem mais óbvia desse novo pipe é que a utilização não requer o uso de pacotes adicionais. Entretanto, se a primeira coisa que você faz quando abre um novo script do R é digitar "library(tidyverse)", isso pode não fazer muita diferença. Além disso, ele é levemente mais eficiente, entretanto é uma diferença muito pequena para ser notada pelo usuário médio.

Agora, para quem pensa em atualizar o R e começar a utilizar o novo pipe, saiba que há dois principais problemas. O primeiro é que em alguns casos o novo pipe demanda uma sintaxe um pouco diferente. O pipe do magritt tem um elemento (".") que nós podemos colocar em casos em que o primeiro elemento da função não é lado esquerdo da expressão. Um desses casos é se estamos interessados em estimar uma regressão por pipe.

reg = mtcars %>%
lm(hp ~ gear, data = .)

O novo operador pipe não tem esse elemento. Para chegar ao mesmo resultado, precisamos fazer uma alteração, utilizando uma função anônima. Aliás, essa também é uma novidade do R 4.1, que criou o  \ (x), que nada mais é do que uma abreviação do "function(x)". O mesmo código acima fica bem menos legível.

reg = mtcars |>
(\ (x) lm(hp ~ gear, data = x))()

 

A outra dificuldade é a utilização deste pipe só é possível para usuários do R 4.1, evidentemente. Códigos escritos com esse operador não funcionarão em versões antigas do R, o que pode ser um entrave para quem trabalha com compartilhamento de código.

Assim, a adoção do novo pipe pela comunidade ainda deve demorar um tempo (isso, se de fato ela ocorrer). Portanto, a recomendação, por enquanto, é aguardar um pouco mais para substituir os pipe do magritt pelo novo pipe.

Receba diretamente em seu e-mail gratuitamente nossas promoções especiais
e conteúdos exclusivos sobre Análise de Dados!

Assinar Gratuitamente
{"cart_token":"","hash":"","cart_data":""}