library(ggplot2)
library(data.table)
# get data, calculate quantities of interest
diam <- diamonds; setDT(diam)
tabulated <- diam[, .N, by = .(cut, color, clarity)]
# plot
ggplot(tabulated, aes(x=2, y=N, fill=color)) +
geom_bar(position = 'fill', stat = 'identity') +
facet_grid(clarity ~ cut) +
xlim(0.5, 2.5) +
coord_polar(theta = 'y') +
labs(x=NULL, y=NULL)
好的,这是如何工作的?让我们看看你的代码-你得到一些看起来像甜甜圈但内部大小不同的图。为什么会这样呢?将数据“拆分”并将输出仅作为条形图查看会很有帮助。 (为简单起见,我将对您的facet进行子集处理,仅选择两行。)
ggplot(subset(diamonds, as.numeric(clarity) <=2),
aes(x = cut, fill = color)) +
geom_bar(position = 'fill', stat = 'bin') +
facet_grid(clarity ~ cut)
您将一个对X进行了映射的值,但它并没有什么有用的作用——它只是偏移了条形图,但由于您正在以该变量进行分面处理,因此每个图中只有一个堆叠的条形图。
然而,当您添加coord_polar
时,具有偏移X值的图形显示为甜甜圈,而x=1的图形显示为饼图。这是因为使用coord_polar
时,堆叠的一系列条形图嵌套在彼此内部,而X=1表示最内部的“线圈”。
因此,解决方案始于不将实际值映射到X。您可以使所有绘图的X=1,但那样会得到所有的饼图,而不是甜甜圈。您想要的是一个堆叠的条形图,在x轴上留出一些空间(那就是甜甜圈的中心)。您可以通过复制数据来实现这一点,这样您就有了两组堆叠的条形图,然后清除第一组。这就是我之前发布的答案,它有效(有关详细信息,请参见编辑历史记录)。
然而,Hadley通过Twitter提出了一个更简单的解决方案,我觉得有义务为后人发布:调整x限制以在x轴上强制一些前导空格。
首先,计算您想要的值(我使用data.table
进行此操作):
library(data.table)
diam <- diamonds; setDT(diam)
tabulated <- diam[, .N, by = .(cut, color, clarity)]
现在,将柱状图堆叠起来并留出一些空间
这是您想要的堆叠条形图,您需要做的就是添加coord_polar
(如本帖顶部所示)。 您可以调整x轴限制以调整甜甜圈/孔比例以适合您的喜好。
diam[, .N, by = .(cut, color, clarity)]
中在进行什么操作?逗号、by=和括号前面的.
代表什么?2) 在plot_data[donutslice==1, N:=0]
中,N:=0
中的冒号代表什么意思? - Usernamedata.table
的术语。 - Axemanaggregate(carat ~ cut + color + clarity, data=diamonds, FUN=length)
得到类似的结果(但现在计数列名为'carat'而不是N)。不过,学习使用 data.table 很棒。 - arvi1000plot_data$N[plot_data$donutslice==1] <- 0
,但是使用 data.table 版本更加简洁! - arvi1000
dput()
共享您绘图中的转换后的数据。想要了解更多制作好的范例的贴士,请参考这里。 - Gregor Thomascut
函数,它比嵌套的ifelse
语句更适合对数值数据进行分组。此外,x %in% c("a", "b", "c")
通常比x == "a" | x == "b" | x == "c"
更好用。 - Gregor Thomasx = cut
替换为x = factor(1)
可以将圆环变成均匀大小的馅饼,但我想制作均匀大小的圆环。 - Username