麻烦与ggplot和geom_bar

时间:2013-01-25 15:17:20

标签: r ggplot2 bar-chart

这里是更新的例子:

df <- data.frame(a=rep(c("A","B"),each=10),
                 b=rep(rep(c("C","D"),each=5),2),
                 c=c(sample(letters[1:5]), sample(letters[6:10]),           
                     sample(letters[1:5]), sample(letters[6:10])),
                 d=c(0.10,0.18,0.34,0.35,0.59,0.16,0.38,0.40,0.53,0.58,
                     0.37,0.62,0.83,1.46,-0.91,-0.79,-0.52,-0.43,-0.01,0.34))

> df
   a b c     d
1  A C b  0.10
2  A C e  0.18
3  A C a  0.34
4  A C c  0.35
5  A C d  0.59
6  A D i  0.16
7  A D j  0.38
8  A D h  0.40
9  A D f  0.53
10 A D g  0.58
11 B C e  0.37
12 B C d  0.62
13 B C a  0.83
14 B C c  1.46
15 B C b -0.91
16 B D f -0.79
17 B D i -0.52
18 B D h -0.43
19 B D j -0.01
20 B D g  0.34

仔细观察,您会看到列d在列b中的排序始终从最小到最大。

第一个情节是我想如何将情节与事实区分开来,显示的条形不是d的顺序。因此,条形从最小到最大不会出现:

p <- ggplot(df, aes(x=c, y=d, fill=b, stat="identity")) +

facet_grid(. ~ a) +

geom_bar()  

print(p)

barplot1

这是因为列c是一个因子,并且因子显然没有按照与列d相同的顺序排序。所以我做了以下事情:

df$c <- paste(1:nrow(df), df$c, sep="_")

df$c <- factor(df$c, levels = unfactor(df$c))

p <- ggplot(df, aes(x=c, y=d, fill=b, stat="identity")) +

            facet_grid(. ~ a) +

            geom_bar()  

print(p)

产生以下图:

enter image description here

这里的顺序是正确的。但是,正如你所看到的,我创造了独特的因素,我得到了那些空间,分别不存在于A和B中。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

我认为这实际上是'ggplot'功能的一个常见错误。如果您设置轮廓颜色(即aes(colour="red")),您将看到实际上正在绘制所有四个值,但它们正在相互叠加。堆叠警告是因为'position'的默认值是“stack”。只需包含position="dodge"参数,即可消失。

现在,要真正解决你的问题。你需要给'ggplot'一些东西来区分X(A),X(B),Y(A)和Y(B)的值。乍一看,您可能会想要使用[b]值,但您不希望所有额外的空格。我们将您的数据帧调整为[b]:

只有1和2
df <- data.frame(a=rep(rep(c("A","B"),each=2),2), 
b=rep(1:2,4), 
c=rep(c("X","Y"),each=4), 
d=c(1.2,1.1,1.15,1.1, -1.1,-1.05,-1.2,-1.08))

一旦你知道问题,情节实际上很容易修复。首先,将[b]设置为x轴,然后将[a]添加到facet。然后使用带有空白元素的“主题”从[b]中删除所有恼人的乱码:

p <- ggplot(NULL, aes(x=b, y=d)) +      
facet_grid(. ~ c + a) +
geom_bar(data = df, stat="identity", position="dodge") +
theme(axis.ticks = element_blank(), axis.text.x = element_blank(), axis.title.x = element_blank())

print(p)

如果这不是你想要的,它应该至少足够接近,你只需要进行整容。祝你好运!

答案 1 :(得分:0)

现在您已经更改了问题,'ggplot'无法为您执行此操作。通过给出[df $ c]级别,您可以对数据进行排序,但仅基于第一组[c]值。例如:

df$c <- factor(df$c, levels=levels(df$c)[order(df$d)])

但这不起作用,因为你试图对[df $ c]进行两次排序(一次为“A”,一次为“B”)。

你真的需要把它分成两个独立的图,然后将两个视口相互拼接。

设置视口

grid.newpage()
pushViewport(viewport(layout = grid.layout(1, 2)))

绘制A

a_df <- df[df$a=="A",]
a_df$c <- factor(a_df$c, levels=levels(a_df$c)[order(a_df$d)])

a_p <- ggplot(a_df, aes(x=1:10, y=d, fill=b)) +
facet_grid(. ~ a) +
geom_bar(stat="identity", position="dodge")

print(a_p, vp = viewport(layout.pos.row=1, layout.pos.col=1))

情节B

b_df <- df[df$a=="B",]
b_df$c <- factor(b_df$c, levels=levels(b_df$c)[order(b_df$d)])

b_p <- ggplot(b_df, aes(x=1:10, y=d, fill=b)) +
facet_grid(. ~ a) +
geom_bar(stat="identity", position="dodge")

print(b_p, vp = viewport(layout.pos.row=1, layout.pos.col=2))

从这里开始,您可以担心删除多余的图例,选择要标记的轴等等,但它看起来与您的示例图完全相同,只删除了空白位置。

这确实是一个例子,说明'ggplot'有时候更像是一种障碍,而不是一种福音。根据我的经验,最好先设计你的情节,然后选择工具。通常情况下,我发现自己会回到原始的'网格'来做我的视觉效果,因为我想要一些'网格'包装'ggplot'不会做的事情。

注意:将来不要删除原始问题内容;只需添加更新的信息。删除旧内容会使此页面上的大量答案和评论无关紧要。