r - 在 ggplot2 中创建华夫饼图和构面
问题描述
有没有什么简单的方法可以结合 ggplot2 中的面创建华夫饼图,或者结合 waffle 包?
例如,用 100 个正方形替换下面的每个条形以表示 1%。
ggplot(mtcars, aes(x = factor(vs), y = hp, fill = as.factor(carb))) +
geom_bar(stat = 'identity', position = 'fill') +
facet_wrap('gear')
解决方案
我不确定我是否会得到stat_waffle()
/geom_waffle()
但你可以使用包中的逻辑来做同样的事情:
library(hrbrthemes)
library(tidyverse)
我们需要计算出百分比,然后让每个组的总和达到 100,所以我们需要一个在 SO 上已经存在了一段时间的辅助函数:
smart_round <- function(x, digits = 0) { # somewhere on SO
up <- 10 ^ digits
x <- x * up
y <- floor(x)
indices <- tail(order(x-y), round(sum(x)) - sum(y))
y[indices] <- y[indices] + 1
y / up
}
waffle
包装中有 2 位“魔法” 。一位是算法的一部分,它只是将因子分量复制正确的次数。我们将按行将以下函数应用于我们将制作的数据框:
waffleize <- function(xdf) {
data_frame(
gear_vs = rep(xdf$gear_vs, xdf$pct),
carb = rep(xdf$carb, xdf$pct)
)
}
现在我们需要:
- 对你的例子做同样的数学 ggplot2
- 计算组的百分比
- 将 % 转换为 100 的部分,并使每组的总和为 100
- 因为我们不能
geom_tile()
在一个面板中有两个不同的 s,所以我们需要修改一个 facet 名称来做同样的事情 - 由上述黑客分组
- 复制每一行
pct
时间 - 确保物品订购正确
- 加入一个 10x10
x
/y
网格以获得尽可能多的方面(在本例中为 6 个);这是华夫饼包装的“魔力”的另一部分 - 画瓷砖
^^ 转换为(这条管道链对于我的舒适度来说有点长,但“它有效”):
count(mtcars, gear, vs, carb, wt=hp) %>%
group_by(gear, vs) %>%
mutate(pct = n/sum(n)) %>%
mutate(pct = (smart_round(pct, 1) * 100L) %>% as.integer()) %>%
select(-n) %>%
ungroup() %>%
mutate(carb = as.character(carb)) %>%
mutate(gear_vs = sprintf("%s-%s", gear, vs)) %>%
select(gear_vs, carb, pct, -gear, -vs) %>%
rowwise() %>%
do(waffleize(.)) %>%
ungroup() %>%
arrange(gear_vs, carb) %>%
bind_cols(
map_df(seq_len(length(unique(.$gear_vs))), ~expand.grid(y = 1:10, x = 1:10))
) %>%
ggplot(aes(x, y)) +
geom_tile(aes(fill=carb), color="white", size=0.5) +
ggthemes::scale_fill_tableau() +
facet_wrap(~gear_vs) +
coord_equal() +
labs(x=NULL, y = NULL) +
hrbrthemes::theme_ipsum_rc(grid="") +
theme(axis.text=element_blank())
推荐阅读
- c++ - 使用 std::hash
对于自定义类 - javascript - 从 Vue 中添加 Google 跟踪代码管理器(在获得同意后)
- java - 使用 Spring Kafka 编写的单元测试 Kafka Consumer
- sql - 创建具有较小存储桶的新 SQL 列(基于文本,而不是数字)
- jquery - showIn 导致表单验证
- php - index.php 页面未加载到 GCE VM 实例的主域上
- python - 将 Pandas 数据框的索引拆分为单独的列
- .net - .Net 控制器接收和处理提交的 PDF 的操作
- javascript - 有没有办法从这些对象中提取数据值
- python - 如何按年扩展/添加行?