使用 ggplot2 的意外 Walker 别名 table 输出

Unexpected Walker alias table output using ggplot2

我正在使用 R 为我在论文中使用的 Walker 别名表创建图形。我已经设法使用 ggplot2 生成了每个图表,除了最后一个分配别名值的图表,因此每列中的概率等于 1。

在创建别名之前按比例缩放的概率图是:

foo <- data.frame(Buscount=c(1,2,3,4,5), Rescaled.busfreq= c(5/9, 10/9, 15/9, 10/9, 5/9))
ggplot(foo, aes(x=factor(Buscount),y=Rescaled.busfreq, fill=factor(Buscount))) +
geom_bar(stat="identity", width=1) + 
scale_fill_manual(values=c("cyan","magenta2","gold","gray","darkolivegreen3", "black")) +
scale_x_discrete(labels=c("a-2", "a-1", "a", "a+1", "a+2"), expand=c(0,0), name="Real count") +
scale_y_continuous(breaks=seq(0,15/9, by=3/9),labels=c("0", "3/9","6/9","9/9", "12/9", "15/9"), expand=c(0,0),
                 name="Adjusted probability of count") +
geom_rect(data=NULL, aes(xmin = 0.5, xmax = 5.5, ymin = 0, ymax = 9/9), color="black", fill=NA, size=1.5) +
geom_vline(xintercept=c(1.5, 2.5, 3.5, 4.5), color="gray") +
theme(panel.grid.minor.y=element_blank(), 
    panel.grid.major.y=element_line(color="gray"),
    panel.background=element_blank(), legend.position="none",
    axis.line = element_line(color="gray", size = 1))

这会产生所需的输出:

我认为 ggplot2 中的堆叠条形图是将值拟合到 1 x 5 平面的最方便方法,但我无法使堆叠条形图起作用。这是我经过多次尝试后得到的代码,并且由于长度超过了原始 data.frame 中的长度,因此我构建了一个新的 data.frame。为了不在值数据中重复列数据,值数据已将 A 替换为 a-2,将 B 替换为 a-1 等等。 0 在那里作为填充符,因此恰好有五个概率对每个 Columns 值有贡献。

Final.Buscount.Alias <- data.frame(Values=rep(c("A","B", "C", "D", "E"), times=5))
Final.Buscount.Alias$Probabilities <- c(5/9,4/9,0,0,0, 0, 6/9, 0, 3/9,0, 0,0,9/9,0,0, 0,0,2/9,7/9,0, 0,0,4/9,0,5/9)
Final.Buscount.Alias$Columns <- rep(c("a-2","a-1", "a", "a+1", "a+2"), each=5)
ggplot(Final.Buscount.Alias, aes(x=factor(Columns),y=Probabilities, fill=factor(Values))) +
geom_bar(stat="identity", width=1) + 
scale_fill_manual(values=c("cyan","magenta2","gold","gray","darkolivegreen3", "black")) +
scale_x_discrete(labels=c("a-2", "a-1", "a", "a+1", "a+2"), expand=c(0,0), name="Real count") +
scale_y_continuous(breaks=seq(0,15/9, by=3/9),labels=c("0", "3/9","6/9","9/9", "12/9", "15/9"), expand=c(0,0),
                 name="Probabilities including alias") +
geom_rect(data=NULL, aes(xmin = 0.5, xmax = 5.5, ymin = 0, ymax = 9/9), color="black", fill=NA, size=1.5) +
geom_vline(xintercept=c(1.5, 2.5, 3.5, 4.5), color="gray") +
theme(panel.grid.minor.y=element_blank(), 
    panel.grid.major.y=element_line(color="gray"),
    panel.background=element_blank(), legend.position="none",
    axis.line = element_line(color="gray", size = 1))

这将生成图表

但是颜色看起来是正确的,但是有一些问题。 a-1 的栏是唯一正确的栏。 a-2 处的柱应位于 aa 处的柱应位于 a-2a+1a+2 几乎是正确的,尽管 - 严格来说 - 列中的条形顺序应该颠倒过来。我试图创建的图表是我在 Excel:

中手动生成的图表

ggplot2里面好像有个顺序我没看懂

我已经阅读了一些堆叠条形图的解决方案here, here, here, here, and here,但我无法弄清楚我做错了什么。

我认为您遇到的关键问题与如何在 R 中设置因子变量的顺序有关。执行 factor(Columns)factor(Values) 会将这些列转换为因子,但顺序是按字母顺序排列的默认。 (要获得不同的顺序,您需要使用 levels 参数显式设置顺序,如下所述。)这意味着 factor(Columns) 将顺序设置为 a、a-1、a-2、一个+1,一个+2。 scale_x_discrete 只是重新标记 x 轴,但不会更改基础数据。这就是为什么最左边的列看起来像列 a(因为它仍然是 a 中的数据)但被重新标记为 a-2

获得所需顺序的方法是使用 factor 函数,但要使用 levels 参数明确指定顺序。在这种情况下,我们希望 Columns 的顺序从 a-2a+2。要以正确的顺序获得堆叠条,我们需要 B 排在 A 之前,D 排在 B 之前。但随后我们还需要移动 C,以便它继续出现在 D 之前。因此,Values 的最终顺序是 C、D、B、A、E,我们可以直接输入 c("C","D","B","A","E") 或使用 built-in LETTERS 向量进行编码:LETTERS[c(3,4,2,1,5)]。我已经按照以下正确顺序设置了您的数据。

我不知道您是否需要图例,但以防万一:默认情况下,图例将根据因子顺序进行排序。但是因为 Values 是字母,您可能希望它们按字母顺序排列。如果是这样,请在 scale_fill_manual 中设置 breaks=LETTERS[1:5](我已在下面完成)。这会更改图例中的顺序,但不会更改图中的因子顺序。

此外,我在 scale_fill_manual 中标记了颜色向量,以确保将所需的颜色分配给 Values 的每个级别(我在其中留下了 "black" ,但未按指定在图中使用)。我很好地进行了其他一些编码更改:例如,geom_col 而不是 geom_bar 以避免需要 stat="identity";删除了 geom_rect 并改为使用 theme 来设置更宽的 panel.border.

library(ggplot2)

Final.Buscount.Alias <- data.frame(Values=rep(c("A","B", "C", "D", "E"), times=5))
Final.Buscount.Alias$Values = factor(Final.Buscount.Alias$Values, 
                                     levels=LETTERS[c(3,4,2,1,5)])

Final.Buscount.Alias$Probabilities <- c(5/9,4/9,0,0,0, 0, 6/9, 0, 3/9,0, 0,0,9/9,0,0, 0,0,2/9,7/9,0, 0,0,4/9,0,5/9)

Final.Buscount.Alias$Columns <- rep(c("a-2","a-1", "a", "a+1", "a+2"), each=5)
Final.Buscount.Alias$Columns = factor(Final.Buscount.Alias$Columns, 
                                      levels=unique(Final.Buscount.Alias$Columns))

ggplot(Final.Buscount.Alias, aes(x=Columns, y=Probabilities, fill=Values)) +
  geom_col(width=1) + 
  scale_fill_manual(values=c(A="cyan",B="magenta2",C="gold",D="gray",E="darkolivegreen3", "black"), breaks=LETTERS[1:5]) +
  scale_x_discrete(expand=c(0,0)) +
  scale_y_continuous(breaks=seq(0, 15/9, by=3/9),
                     labels=c("0", paste0(seq(3,15,3),"/9")), 
                     expand=c(0,0)) +
  geom_vline(xintercept=c(1.5, 2.5, 3.5, 4.5), color="gray30") + # Darkened this to make it obvious where the lines are. Remove this line of code if you want the colors to abut each other.
  labs(x="Real Count", y="Probabilities including alias") +
  theme(panel.border=element_rect(size=2, fill=NA))