使用ggplot在R中的100%堆积柱形图中创建日志轴

时间:2013-09-06 06:23:39

标签: r excel graph plot ggplot2

我有百分比的数据。我想用ggplot来创建一个图形,但是我不能像我想的那样让它工作。由于数据非常偏斜,因此简单的堆叠列不能很好地工作,因为真正的小值不会显示。这是一个样本集:

    Actual  Predicted
a   0.5     5
b   9.5     5
c   90      90

左边是excel图,右边是R-ggplot

Excel Rplot

问题是在R中,列不会叠加起来。

这是我的R代码:

a = c("a","b","c","a","b","c")
b = c("Actual","Actual","Actual","Predicted","Predicted","Predicted")
c = c(0.5,2.5,97,0.2,2.2,97.6)
c = c+1

dat = data.frame(Type=a, Case=b, Percentage=c)
ggplot(dat, aes(x=Case, y=Percentage, fill=Type)) + geom_bar(stat="identity") + scale_y_log10()

*在Excel和R中我都用+1来处理数字0-1,所以y轴略微偏离

如果我使用:

ggplot(dat, aes(x=Case, y=Percentage, fill=Type)) + geom_bar(stat="identity",position = "fill") + scale_y_log10()

总高度匹配,但两个蓝色部分的大小不一致(它们都是90%)

enter image description here

2 个答案:

答案 0 :(得分:4)

仅仅因为两组数字加起来相同(在这种情况下为103)并不意味着日志的总和将加起来相同的值!当您堆叠条形而没有“填充”时,您会得到不同的高度,因为值的日志总和是不同的。然后,当你将它们全部缩放到相同的高度时,你必须按不同的速率将蓝色框压扁,因此它们看起来不同。

Excel条形图故意误导。左侧红色条与其上方的蓝色条相同,但表示蓝色条的十分之一左右的值。你不能在比例的对数比例上制作条形图 - 这是错误的。

有一种很好的方式可以显示小数字而不会丢失或歪曲它们。它是一种令人惊叹的可视化技术,称为“在表格中编写数字”。

答案 1 :(得分:1)

我设法让它像excel一样工作。像Spacedman所说的那样,情节在视觉上有误导性,但在数字上是正确的。原因是我们想要比较条形段的实际高度,在数字上你需要查看y轴的起始值和结束值。它类似于没有y轴最小值为零的条形图。这是一个example

我不确定是否会使用该方法来显示我的数据,但我必须弄明白。

结果如下:

enter image description here

这是代码(我可能将其清理为在ggplot中分配y值时可以调用的函数)。

a = c("a","b","c","a","b","c")
b = c("Actual","Actual","Actual","Predicted","Predicted","Predicted")
c = c(0.5,9.5,90,5,5,90)
c = c+1
dat = data.frame(Type=a, Case=b, Percentage=c, Cumsum_L=c, Cumsum=c, Norm=c)
for(i in 1:length(dat$Percentage)){
    cumsum=0
    for(j in 1:i){
        if(dat$Case[j]==dat$Case[i]){
            cumsum=cumsum+(dat$Percentage[j])
        }
    }
    dat$Cumsum_L[i]=cumsum-dat$Percentage[i]
    dat$Cumsum[i]=cumsum
    if(dat$Cumsum_L[i]==0){
        dat$Cumsum_L[i]=1
    }
    dat$Norm[i] = log(dat$Cumsum[i])-log(dat$Cumsum_L[i])
}
intervals = seq(from = 0, to = 100, by = 10)
intervals_log = log(intervals)
intervals_log[1]=0

ggplot(dat, aes(x=Case, y=Norm, fill=Type)) + geom_bar(stat="identity") +
    scale_y_continuous(name="Percent",breaks = intervals_log, labels=intervals )

*我还需要修复端点+1有点事。

**我也可能正在屠杀数学。