欢迎关注R语言数据分析指南
加载R包
代码语言:javascript
复制library(tidyverse)
# devtools::install_github('erocoar/ggpol')
library(ggpol)
导入数据
代码语言:javascript
复制df <- read_tsv("data.xls")
数据清洗
代码语言:javascript
复制results <- df %>%
group_by(constituency, gender, status) %>% # 分组处理
summarise(count = sum(count)) %>% # 计算每组的数量
ungroup() %>% # 解除分组
unite(col = "status_gender", gender, status, sep = "_") %>% # 将性别和选举状态合并成一个新的列
pivot_wider(names_from = status_gender, values_from = count) %>% # 长表转宽表
mutate(ratio = female_elected / male_elected) %>% # 统计性别比率
gather(key = category, value = count, -constituency, -ratio) %>% # 宽表转长表
separate(category, into = c("gender", "status")) %>% # 将category列分成性别和状态两列
uncount(count) %>% # 根据count列的值,将行复制相应的次数
group_by(constituency, gender) %>%
mutate(y = sequence(n())) %>% # 为每组生成一个序列号
mutate(y = ifelse(gender == "female", -y, y)) %>% # 如果是女性,将序列号取反
ungroup() %>% # 解除分组
mutate(status_label = case_when(status == "elected" ~ "elected",
status == "notelected" ~ "not elected"),
gender_label = case_when(gender == "female" ~ "Female candidates", # 添加性别标签
gender == "male" ~ "Male candidates"),
dominant_gender = case_when(status == "notelected" ~ "not elected", # 添加主导性别标签
status == "elected" & ratio > 1 ~ "Female majority elected",
status == "elected" & ratio < 1 ~ "Male majority elected",
status == "elected" & ratio == 1 ~ "Gender balance")) %>%
mutate_if(is.character, factor) # 将字符列转换为因子
构建数据用于在图形中添加空白区域
代码语言:javascript
复制dummy_constituency =
tibble(y = c(-max(results$y), 0, 0, max(results$y)), # y值为最大最小值及其负值
gender = c("female", "female", "male", "male")) %>% # 性别列
mutate(gender_label = case_when(gender == "female" ~ "Female candidates", # 添加性别标签
gender == "male" ~ "Male candidates"))
数据可视化
代码语言:javascript
复制ggplot()
geom_point(data = results, # 添加点图层,使用处理后的选举数据
mapping = aes(x = constituency,y = y,color = dominant_gender), # 映射选区、y值和主导性别
shape = 19,size = 4)
geom_blank(data = dummy_constituency, # 添加空白图层,使用虚拟选区数据
mapping = aes(y = y))
ggpol::facet_share(~ gender_label, dir = "h", scales = "free", reverse_num = TRUE) # 分面显示,根据性别标签分面
coord_flip() # 翻转坐标轴,使选区显示在y轴
scale_x_discrete(name = NULL,expand = c(0,1), # 调整x轴比例和标签
limits = rev(levels(results$constituency)))
scale_y_continuous(name = NULL, breaks = NULL,expand = c(0,1)) # 调整y轴比例和标签
scale_color_manual(name = NULL, values = c("indianred2", "palegreen3", "skyblue2", "grey87")) # 手动设置颜色
theme(panel.grid = element_blank(), # 调整图形主题
legend.position = "bottom",
strip.text = element_text(size = 12),
legend.text = element_text(size = 10),
plot.background = element_blank(),
panel.background = element_blank(),
strip.background = element_blank(),
legend.background = element_blank(),
legend.key = element_blank(),
legend.spacing.x = unit(0,"cm"),
plot.margin = margin(0.2,0.2,1,-100))