2010-12-02 84 views
9

我正在寻找一种方式来绘制包含两个不同系列的条形图,隐藏其中一个系列的条形图,而是有一条线(如果可能,则平滑)通过隐藏系列的条形顶部(类似于在直方图上覆盖频率多项式的方式)。我试过下面的例子,但似乎遇到了两个问题。如何使用ggplot2将线条覆盖在条形图上?

首先,我需要按组总结(总计)数据,其次,我想将其中一个系列(df2)转换为一行。

df <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,1,2,2,3,3)) 
df2 <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,4,3,5,1,2)) 
ggplot(df, aes(x=grp, y=val)) + 
    geom_bar(stat="identity", alpha=0.75) + 
    geom_bar(data=df2, aes(x=grp, y=val), stat="identity", position="dodge") 

回答

11

也许您的样本数据并不代表您正在使用的真实数据,但是没有要绘制的线条df2。每个x和y值只有一个值。这是你的df2的修饰的版本有足够的数据点来构造线:

df <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,2,3,1,2,3)) 
df2 <- data.frame(grp=c("A","A","B","B","C","C"),val=c(1,4,3,5,0,2)) 

p <- ggplot(df, aes(x=grp, y=val)) 
p <- p + geom_bar(stat="identity", alpha=0.75) 

p + geom_line(data=df2, aes(x=grp, y=val), colour="blue") 

或者,如果你上面的例子数据正确,你可以绘制此信息与geom_point(data = df2, aes(x = grp, y = val), colour = "red", size = 6)点。你显然可以根据自己的喜好改变颜色和大小。

编辑:在回答评论

我不完全知道是什么的频率多项式在直方图视觉应该是什么样子。 x值是否应该相互连接?其次,你一直提到想要的行,但你的代码显示geom_bar(),我认为这不是你想要的?如果您需要线路,请使用geom_lines()。如果上面的两个假设是正确的,那么这里有一个方法来做到这一点:

#First let's summarise df2 by group 
df3 <- ddply(df2, .(grp), summarise, total = sum(val)) 
> df3 
    grp total 
1 A  5 
2 B  8 
3 C  3 

#Second, let's plot df3 as a line while treating the grp variable as numeric 

p <- ggplot(df, aes(x=grp, y=val)) 
p <- p + geom_bar(alpha=0.75, stat = "identity") 
p + geom_line(data=df3, aes(x=as.numeric(grp), y=total), colour = "red") 
+0

事实上,我正在寻找一种方式来绘制基本上包含两种不同系列的一个柱状图,隐藏的酒吧之一,而是有一个线(平滑如果可能的话)经过顶部(隐藏序列的条纹会出现在哪里)(类似于在直方图上覆盖频率多项式的方式)。 – user338714 2010-12-02 13:49:18

+0

我澄清了原来的问题。感谢您迄今为止的帮助 - 看起来我错过了首先总结数据的步骤。 – user338714 2010-12-02 14:02:24

17

您可以通过多种方式获得组总数。其中之一是

with(df, tapply(val, grp, sum)) 

为简单起见,您可以将条形和线条数据组合到一个数据集中。

df_all <- data.frame(grp = factor(levels(df$grp))) 
df_all$bar_heights <- with(df, tapply(val, grp, sum)) 
df_all$line_y <- with(df2, tapply(val, grp, sum)) 

条形图使用分类x轴。要覆盖一条线,您需要将轴转换为数字。

ggplot(df_all) + 
    geom_bar(aes(x = grp, weight = bar_heights)) + 
    geom_line(aes(x = as.numeric(grp), y = line_y)) 

enter image description here