Uma amiga perguntou se eu poderia replicar o seguinte gráfico:
Para fazer isso, eu precisava recriar os dados primeiro. Eu fiz isso como se os dados estivessem organizados da seguinte forma:
# Country Ages_35_plus Ages_18_34
# 1 Germany 0.39 0.81
# 2 France 0.42 0.83
# 3 Vietnam 0.49 0.86
# 4 Japan 0.43 0.78
# 5 Poland 0.51 0.86
# 6 Lebanon 0.57 0.90
# 7 Australia 0.60 0.91
# 8 South Korea 0.45 0.75
# 9 Canada 0.65 0.93
# 10 Spain 0.57 0.85
# 11 Italy 0.57 0.83
# 12 Peru 0.65 0.91
# 13 U.S. 0.63 0.89
# 14 UK 0.59 0.84
# 15 Mexico 0.67 0.90
# 16 Chile 0.75 0.96
# 17 China 0.52 0.73
# 18 India 0.48 0.69
# 19 Pais A 0.60 0.40
# 20 Pais B 0.50 0.50
Eu incluí Pais A
e Pais B
para que eu tenha um país com uma diferença negativa, e outro
com uma diferença de zero.
Dado isso, eu precisava fazer 4 coisas antes de começar:
1) Insirir uma quebra de linha em South Korea
2) Calcular as diferenças de idade
3) Classificar os países pelas diferenças de idade
4) Definir os nomes dos países como fatores para que possamos plotá-los na ordem correta.
# ************************************************************************* ----
# Pacotes ----
# ************************************************************************* ----
#install.packages("tidyverse")
library("tidyverse")
# ************************************************************************* ----
# Cores - A partir do Original ----
# ************************************************************************* ----
laranja <- "#e8ab5f"
verde <- "#a1ad62"
fundo_diferencas <- "#eef0e2"
cinza <- "#bbbbbb"
cinza_claro <- "#f4f4f4"
# ************************************************************************* ----
# Dados para Grafico de Pontos ----
# ************************************************************************* ----
# Adicionei dois paises: Pais A e Pais B e vou colocar um com diferenca igual
# a zero e o outro com a diferenca negativa para testar
base_original <-
data.frame(
Country = c("Germany", "France", "Vietnam", "Japan",
"Poland", "Lebanon", "Australia",
"South Korea", "Canada", "Spain", "Italy", "Peru", "U.S.",
"UK", "Mexico", "Chile", "China", "India",
"Pais A", "Pais B"
),
Ages_35_plus = c(0.39, 0.42, 0.49, 0.43,
0.51, 0.57, 0.60,
0.45, 0.65, 0.57, 0.57, 0.65, 0.63,
0.59, 0.67, 0.75, 0.52, 0.48,
0.6, 0.5
),
Ages_18_34 = c(0.81, 0.83, 0.86, 0.78, 0.86, 0.90, 0.91,
0.75, 0.93, 0.85, 0.83, 0.91, 0.89,
0.84, 0.90, 0.96, 0.73, 0.69,
0.4, 0.5
)
)
## A base original esta assim:
# Country Ages_35_plus Ages_18_34
# 1 Germany 0.39 0.81
# 2 France 0.42 0.83
# 3 Vietnam 0.49 0.86
# 4 Japan 0.43 0.78
# 5 Poland 0.51 0.86
# 6 Lebanon 0.57 0.90
# 7 Australia 0.60 0.91
# 8 South Korea 0.45 0.75
# 9 Canada 0.65 0.93
# 10 Spain 0.57 0.85
# 11 Italy 0.57 0.83
# 12 Peru 0.65 0.91
# 13 U.S. 0.63 0.89
# 14 UK 0.59 0.84
# 15 Mexico 0.67 0.90
# 16 Chile 0.75 0.96
# 17 China 0.52 0.73
# 18 India 0.48 0.69
# 19 Pais A 0.60 0.40
# 20 Pais B 0.50 0.50
## A partir disso, precisamos:
## 1) Quebrar o texto da South Korea
## 2) Pegar as diferencas
## 3) Ordenar pelas diferencas
## 4) Colocar o nome dos paises como fatores, para que possamos plotar os paises
## na ordem certa (maior diferenca para a menor)
# _________________________________________________________________________ ====
## \__Quebrar Texto
base_original_v2 <-
base_original %>%
mutate(
Country = ifelse(
Country == "South Korea",
# Verdadeiro:
"South \n Korea",
# Falso:
as.character(Country))
)
# _________________________________________________________________________ ====
## \__Pegar Diferencas
base_diff <-
base_original_v2 %>%
mutate(
Diferenca = Ages_18_34-Ages_35_plus
) %>%
# Ordenar (isso vai ordenar do menor para o maior, mas tudo bem, pois o ggplot
# inverte a ordem - coloca do maior para o menor na hora de plotar)
arrange(Diferenca, desc(Country)) %>%
# Criar fatores a partir do nomes dos paises ordenados
mutate(
Country.fact = factor(Country, levels = unique(Country))
)
## Com isso, a base fica assim:
# Country Ages_35_plus Ages_18_34
# 1 Germany 0.39 0.81
# 2 France 0.42 0.83
# 3 Vietnam 0.49 0.86
# 4 Japan 0.43 0.78
# 5 Poland 0.51 0.86
# 6 Lebanon 0.57 0.90
# 7 Australia 0.60 0.91
# 8 South \n Korea 0.45 0.75
# 9 Canada 0.65 0.93
# 10 Spain 0.57 0.85
# 11 Italy 0.57 0.83
# 12 Peru 0.65 0.91
# 13 U.S. 0.63 0.89
# 14 UK 0.59 0.84
# 15 Mexico 0.67 0.90
# 16 Chile 0.75 0.96
# 17 China 0.52 0.73
# 18 India 0.48 0.69
# 19 Pais A 0.60 0.40
# 20 Pais B 0.50 0.50
# _________________________________________________________________________ ====
## \__Agregar por Idade
## Para Plotar as Duas Idades na Mesma linha, temos que modificar a base
## Queremos deixar ela assim (mostrando apenas uma parte, pra nao ficar grande):
# Country Age_Group Age_Percent Diferenca
# 1 Germany Ages_35_plus 0.39 0.42
# 2 France Ages_35_plus 0.42 0.41
# 3 Vietnam Ages_35_plus 0.49 0.37
# 4 Japan Ages_35_plus 0.43 0.35
# 5 Poland Ages_35_plus 0.51 0.35
# 6 Lebanon Ages_35_plus 0.57 0.33
# 7 Australia Ages_35_plus 0.60 0.31
# 8 Germany Ages_18_34 0.81 0.42
# 9 France Ages_18_34 0.83 0.41
# 10 Vietnam Ages_18_34 0.86 0.37
# 11 Japan Ages_18_34 0.78 0.35
# 12 Poland Ages_18_34 0.86 0.35
# 13 Lebanon Ages_18_34 0.90 0.33
# 14 Australia Ages_18_34 0.91 0.31
# Note que o valor da diferenca esta duplicado por grupo
# Lidaremos com isso depois
# Para deixar a base do jeito acima:
base_diff_agregada <-
base_diff %>%
gather(
# Nome do Grupo
key = Age_Group,
# Nome da Variavel onde os percentuais de Idade entrarao
value = Age_Percent,
# Quais variaveis entrarao
Ages_35_plus, Ages_18_34
) %>%
# Reordenar as variaveis na base
select(Country, Country.fact, Age_Group, Age_Percent, Diferenca)
#___________________________________________________________________________####
# ************************************************************************* ----
# Grafico de Pontos ----
# ************************************************************************* ----
p<-
ggplot(
data = base_diff_agregada,
mapping = aes(
# Eixo Y
y=Country.fact,
# Eixo X
x=Age_Percent,
# Grupos com cores diferentes
# Se diferenca for zero, participa de um terceiro grupo
color = ifelse(Diferenca == 0, "zero", Age_Group))
) +
# Plotar as linhas entre pontos, por Pais
geom_line(
mapping = aes(group = Country),
color = cinza,
size = 2.5
) +
geom_point(
# tamanho do ponto
size=4,
# tipo de icone do ponto. importante ser o numero 19, senao nao tem como
# plotar as cores para os grupos diferentes
pch = 19
) +
# Adicionar os percentuais para cada ponto
geom_text(
# Tamanho da Letra
size = 4,
# Colocar um pouco abaixo dos pontos
nudge_y = -0.35,
mapping =
aes(
label =
# Se o pais eh Germany, plotar os numeros com o simbolo %
ifelse(Country == "Germany",
# Verdadeiro:
paste0(as.character(round(Age_Percent*100,0)),"%"),
# Falso
paste0(as.character(round(Age_Percent*100,0)))
),
color = ifelse(Diferenca == 0, "zero", Age_Group)
)
) +
# Adicionar "Legenda" acima apenas dos valores do primeiro grupo (germany)
geom_text(
# Tamanho da Letra
size = 4,
# Negrito
fontface = "bold",
# Colocar um pouco acima dos pontos
nudge_y = 0.6,
mapping =
aes(
label =
# Se o pais eh Germany, plotar a legenda
ifelse(Country == "Germany",
# Verdadeiro:
ifelse(Age_Group == "Ages_35_plus",
# Verdadeiro:
"Ages 35+",
# Falso:
"Ages 18-34"
),
# Falso
""
),
color = ifelse(Diferenca == 0, "zero", Age_Group)
)
) +
# Mudar Cores
scale_color_manual(
# Se diferenca for 0, plotar cinza, caso contrario, plotar com as
# cores por grupo
values = c(laranja, verde, "gray")
) +
# Mudar escala eixo X
scale_x_continuous(
# Limite de 0 a 1.2 (nao vai de 0 a 1 pq precisamos de um espaco apos o 1,
# para colocar os valores da diferenca)
limits = c(0,1.2),
# Mostrar texto a cada 25%
breaks = seq(0,1,.25),
# Mudar escala para percentual
labels = scales::percent
) +
# Aumentar escala eixo y para caber as legendas
scale_y_discrete(
expand = expand_scale(add=c(0.65,1))
) +
# Inserir Retangulo em Branco para delimitar a area onde ficarao os valores
# das diferencas
geom_rect(
mapping = aes(xmin = 1.01, xmax = Inf , ymin = -Inf, ymax = Inf),
fill = "white",
color = "white"
) +
# Inserir Retangulo para as diferencas
geom_rect(
mapping = aes(xmin = 1.05, xmax = 1.15 , ymin = -Inf, ymax = Inf),
fill = fundo_diferencas,
color = fundo_diferencas
) +
# Inserir Valores das Diferencas
geom_text(
# Negrito
fontface = "bold",
# Tamanho da Letra
size = 4,
# Cor
colour = "black",
# Posicao
mapping =
aes(
x = 1.1,
y = Country,
label =
# Para evitar valor duplicado da diferenca, plotar vazio para o
# primeiro grupo e plotar a diferenca apenas para o grupo Ages_18_34.
ifelse(Age_Group == "Ages_35_plus",
# Verdadeiro
"",
#Falso
# Se a Diferenca for igual a zero, nao colocar nenhum sinal.
# Caso contratio, se for Positiva, colocar sinal + na frente.
# Colocar sinal -, caso contrario
ifelse(Diferenca == 0,
# Verdadeiro:
paste0(as.character(round(Diferenca*100,0))),
# Falso
ifelse(Diferenca > 0,
# Verdadeiro
paste0("+",as.character(round(Diferenca*100,0))),
# Falso (nao precisa colocar o simbolo -)
paste0(as.character(round(Diferenca*100,0)))
)
)
)
)
) +
# Inserir Titulo das Diferencas
geom_text(
# Negrito
fontface = "bold",
# Tamanho da Letra
size = 4,
# Cor
colour = "gray",
# Colocar um pouco acima dos pontos
nudge_y = 0.6,
# Posicao
mapping =
aes(
x = 1.1,
y = Country,
label =
# Plotar acima apenas dos valores do primeiro grupo (germany)
ifelse(Country == "Germany",
# Verdadeiro
"DIFF",
#Falso
""
)
)
) +
# Titulo e Labels dos Eixos
labs(
title = "The social media age gap",
subtitle = paste0(
"Adult internet users or reported smartphone owners who \n",
"use social networking sites"
),
x = "",
y = ""
) +
# Mudar Fundo, Tamanho das Letras, Etc.
theme(
# Mudar Fonte de todos os textos
text = element_text(color = "#4e4d47", size = 14),
# Colocar nome dos Paises em Negrito
axis.text.y = element_text(face = "bold"),
# Separar mais o texto do eixo dos percentuais do grafico
axis.text.x = element_text(vjust = -0.75),
# Excluir ticks
axis.ticks = element_blank(),
# Excluir Legenda Original
legend.position = "none",
# Fundo Branco
panel.background = element_blank(),
# Linhas por Country
panel.grid.major.y = element_line(colour = cinza_claro, size = 1),
# Mudar Fonte Titulo
plot.title = element_text(face = "bold", size = 16),
# Mudar Fonte Sub-Titulo e Adicionar Margem
plot.subtitle = element_text(face = "italic", size = 12,
margin = margin(b = 0.5, unit = "cm"))
)
p
E o gráfico final: