2016-11-04 15 views
0

我使用ggplot2创建带有标准偏差条的条形图。我的数据帧是相当大的,但这里是例如截短版本:如何将我的barplot中的标准偏差条限制为最大值?

SampleName Target.ID Maj.Allele.Freq SD AVG.MAF 
W15-P2-1 rs1005533 99.74811083 24.98883743 93.70753223 
W15-P2-2 rs1005533 100 24.98883743 93.70753223 
W15-P2-3 rs1005533 100 24.98883743 93.70753223 
W15-P2-4 rs1005533 100 24.98883743 93.70753223 
W15-P2-1 rs1005533 99.94819995 24.98883743 93.70753223 
W15-P2-2 rs1005533 100 24.98883743 93.70753223 
W15-P2-3 rs1005533 100 24.98883743 93.70753223 
W15-P2-4 rs1005533 100 24.98883743 93.70753223 
W21-P2-1 rs1005533 100 24.98883743 93.70753223 
W21-P2-2 rs1005533 100 24.98883743 93.70753223 
W21-P2-3 rs1005533 99.90044798 24.98883743 93.70753223 
W21-P2-4 rs1005533 99.72375691 24.98883743 93.70753223 
W21-P2-1 rs1005533 100 24.98883743 93.70753223 
W21-P2-2 rs1005533 100 24.98883743 93.70753223 
W21-P2-3 rs1005533 100 24.98883743 93.70753223 
W21-P2-4 rs1005533 0 24.98883743 93.70753223 
W15-P2-1 rs10092491 52.40641711 1.340954343 51.8604281 
W15-P2-2 rs10092491 53.69923603 1.340954343 51.8604281 
W15-P2-3 rs10092491 52.56689284 1.340954343 51.8604281 
W15-P2-4 rs10092491 50.11764706 1.340954343 51.8604281 
W15-P2-1 rs10092491 50.30094583 1.340954343 51.8604281 
W15-P2-2 rs10092491 50.96277279 1.340954343 51.8604281 
W15-P2-3 rs10092491 50.94102886 1.340954343 51.8604281 
W15-P2-4 rs10092491 51.2849162 1.340954343 51.8604281 
W21-P2-1 rs10092491 53.56976202 1.340954343 51.8604281 
W21-P2-2 rs10092491 50.27861123 1.340954343 51.8604281 
W21-P2-3 rs10092491 52.8358209 1.340954343 51.8604281 
W21-P2-4 rs10092491 51.42585551 1.340954343 51.8604281 
W21-P2-1 rs10092491 52.77890467 1.340954343 51.8604281 
W21-P2-2 rs10092491 52.89017341 1.340954343 51.8604281 
W21-P2-3 rs10092491 53.70786517 1.340954343 51.8604281 
W21-P2-4 rs10092491 50 1.340954343 51.8604281 

因为在最后一列(AVG.MAF)能产生标准差条超过最大的100的平均值,该图显示的条超出上的100

Example Standard Deviation bars extend beyond 100.

这里y轴的极限是创建上述情节的代码:

pe1 = ggplot(half1, aes(x=Target.ID, y=AVG.MAF))+ 
geom_bar(stat = "identity", position = "dodge", colour = "black", 
width = 0.5, fill = "yellowgreen")+xlab("")+ 
ylab("Average Major Allele Frequency")+ 
labs(title="Allele Balance AmpliSeq Identity Sample P2")+ 
geom_errorbar(aes(ymin = AVG.MAF-SD, ymax = AVG.MAF+SD), 
width = 0.4, position = position_dodge(0.9), 
    size = 0.6)+ 
theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = .5)) 

我试图截断使用coord_cartesian的情节,那种这使剧情看起来像我隐藏一些数据:

Here the top of the standard deviation bars is cut off

这里是代码来创建与标准差条情节切断:

pe1 = ggplot(half1, aes(x=Target.ID, y=AVG.MAF))+geom_bar(stat = "identity", position = "dodge", colour = "black", width = 0.5, fill = "yellowgreen")+xlab("")+ylab("Average Major Allele Frequency")+labs(title="Allele Balance AmpliSeq Identity Sample P2")+geom_errorbar(aes(ymin = AVG.MAF-SD, ymax = AVG.MAF+SD), width = 0.4, position = position_dodge(0.9), size = 0.6)+theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = .5))+coord_cartesian(ylim=c(0,100)) 

似乎必须有一种方法来将标准偏差条限制为我预期的ymax为100,并且仍然保持顶部水平条在图中可见。有谁知道如何做到这一点?

+6

为什么要通过截断标准开发栏的顶部来歪曲标准偏差? – Nate

+1

'... geom_errorbar(aes(ymin = AVG.MAF-SD,ymax = pmin(AVG.MAF + SD,100)...'做你想做的事情?几乎可以肯定的是, ,可能是因为使用的基础错误模型是不合适的 – Miff

+0

@NathanDay和Miff你们都给了我一些想法,谢谢你们对你们的意见和可能的解决方案 – aminards

回答

0

除了人在意见中提出的问题,这里有一些其他方面的考虑:

  1. 你并不需要添加重复的平均值为您的数据的每一行一列。相反,您可以使用Maj.Allele.Freq中的实际数据值计算并绘制ggplot中的平均值。 (实际上,通过使用y值的列来重复每个Target.ID的平均值,您实际上绘制了平均值的多个副本,一个在另一个之上。)

    您也可以汇总ggplot之外的数据(即计算平均值和标准偏差),然后使用汇总数据框进行绘图。在更复杂的情况下,这有时是必需的,但您可以在ggplot中完成。

  2. 在我看来,点比这里的酒吧更好。

下面的代码同时提供点和酒吧版本,并且还示出了如何添加任一数据的标准偏差或数据的平均值的95%置信区间。蓝线表示标准偏差,而红线表示95%置信区间。

我提供了自举置信区间。为了提供经典的正常置信区间,从mean_cl_boot切换到mean_cl_normal

如果您希望y轴下降到零,请添加coord_cartesian(ylim=c(0,150))或您希望的任何最大y值(正如评论所讨论的,为避免误导性图形,它应该高于错误栏的顶部,不管条形图是代表SD还是CI)。

ggplot(half1, aes(x=Target.ID, y=Maj.Allele.Freq)) + 
    stat_summary(fun.data=mean_sdl, geom="errorbar", width=0.1, colour="blue") + 
    stat_summary(fun.data=mean_sdl, geom="point", colour="blue", size=3) + 
    stat_summary(fun.data = mean_cl_boot, colour="red", geom="errorbar", width=0.1) + 
    stat_summary(fun.data = mean_cl_boot, colour="red", geom="point") + 
    labs(x="", y="Average Major Allele Frequency", 
     title="Allele Balance AmpliSeq\nIdentity Sample P2") + 
    theme_bw() + 
    theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = .5)) 

enter image description here

ggplot(half1, aes(x=Target.ID, y=Maj.Allele.Freq)) + 
    stat_summary(fun.y=mean, geom="bar", fill="yellowgreen", colour="black") + 
    stat_summary(fun.data=mean_sdl, geom="errorbar", width=0.1, size=1, colour="blue") + 
    stat_summary(fun.data = mean_cl_boot, colour="red", geom="errorbar", width=0.1, size=0.7) + 
    labs(x="", y="Average Major Allele Frequency", 
     title="Allele Balance AmpliSeq\nIdentity Sample P2") + 
    theme_bw() + 
    theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = .5)) 

enter image description here

你也可以把两块SD和95%CI在同一个情节:

pnp = position_nudge(x=0.1) 
pnm = position_nudge(x=-0.1) 

ggplot(half1, aes(x=Target.ID, y=Maj.Allele.Freq)) + 
    stat_summary(fun.data=mean_sdl, geom="errorbar", width=0.1, position=pnp, aes(colour="SD")) + 
    stat_summary(fun.data=mean_sdl, geom="point", position=pnp, aes(colour="SD")) + 
    stat_summary(fun.data = mean_cl_boot, geom="errorbar", width=0.1, 
       position=pnm, aes(colour="95% CI")) + 
    stat_summary(fun.data = mean_cl_boot, geom="point", position=pnm, aes(colour="95% CI")) + 
    labs(x="", y="Average Major Allele Frequency", colour="", 
     title="Allele Balance AmpliSeq\nIdentity Sample P2") + 
    theme_bw() + 
    theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = .5)) 

enter image description here

+0

我总是在这里学到新的东西,我不知道我可以从ggplot中进行计算,谢谢你的详细解答。我可以根据需要进行一些调整,评论者是正确的,切断SD栏是没有意义的,但现在我知道如何去做。 – aminards

+0

您可以创建将数据框混乱,然后绘制(在更复杂的情况下有时是必需的,但不在这里),或者可以在ggplot中进行计算。无论哪种方式,您都不需要添加一个反复重复平均值的列,实际上这样做会导致每个条的多个副本被绘制成一个在另一个之上。我已经更新了我的答案来讨论这个问题。 – eipi10