ggplot scale_y_log10()问题

时间:2012-02-29 15:35:08

标签: r ggplot2

我使用ggplot进行缩放时遇到了一个有趣的问题。我有一个数据集,我可以使用默认的线性刻度来很好地绘制,但是当我使用scale_y_log10()时,数字就会消失。这是一些示例代码和两张图片。请注意,线性标度中的最大值为~700,而日志缩放产生的值为10 ^ 8。我告诉你整个数据集只有大约8000个条目,所以有些东西不对。

我认为这个问题与我的数据集结构和分箱有关,因为我无法在像'钻石'这样的常见数据集上复制此错误。但是我不确定排除故障的最佳方法。

感谢, zach cp


编辑:bdamarest可以重现钻石数据集上的比例问题,如下所示:

example_1 = ggplot(diamonds, aes(x=clarity, fill=cut)) + 
  geom_bar() + scale_y_log10(); print(example_1)

#data.melt is the name of my dataset    
> ggplot(data.melt, aes(name, fill= Library)) + geom_bar()  
> ggplot(data.melt, aes(name, fill= Library)) + geom_bar()  + scale_y_log10()
> length(data.melt$name)
[1] 8003 

linear scale log scale

这里有一些示例数据......我想我看到了这个问题。原始熔化的数据集可能已经长约10 ^ 8行。也许行号被用于统计数据?

> head(data.melt)
       Library         name               group
221938      AB Arthrofactin        glycopeptide
235087      AB   Putisolvin      cyclic peptide
235090      AB   Putisolvin      cyclic peptide
222125      AB Arthrofactin        glycopeptide
311468      AB     Triostin cyclic depsipeptide
92249       AB          CDA         lipopeptide


> dput(head(test2))
structure(list(Library = c("AB", "AB", "AB", "AB", "AB", "AB"
), name = c("Arthrofactin", "Putisolvin", "Putisolvin", "Arthrofactin", 
"Triostin", "CDA"), group = c("glycopeptide", "cyclic peptide", 
"cyclic peptide", "glycopeptide", "cyclic depsipeptide", "lipopeptide"
)), .Names = c("Library", "name", "group"), row.names = c(221938L, 
235087L, 235090L, 222125L, 311468L, 92249L), class = "data.frame")

更新:

行号不是问题。以下是使用相同的aes x轴和填充颜色绘制的相同数据,并且缩放完全正确:

> ggplot(data.melt, aes(name, fill= name)) + geom_bar()
> ggplot(data.melt, aes(name, fill= name)) + geom_bar() + scale_y_log10()
> length(data.melt$name)
[1] 8003

enter image description here enter image description here

1 个答案:

答案 0 :(得分:36)

geom_barscale_y_log10(或任何对数刻度)不能很好地协同工作,并且不会给出预期的结果。

第一个基本问题是条形变为0,并且在对数标度上,0变为负无穷大(这很难绘制)。围绕这个的婴儿床通常从1开始而不是0(因为$ \ log(1)= 0 $),如果有0个计数就没有绘制任何东西,并且不担心失真,因为如果需要对数刻度,你可能不会关心被1关(不一定是真的,但......)

我正在使用@dbemarest显示的diamonds示例。

一般来说,这样做是为了变换坐标,而不是缩放比例(后面的差异更多)。

ggplot(diamonds, aes(x=clarity, fill=cut)) +
  geom_bar() +
  coord_trans(ytrans="log10")

但这会产生错误

Error in if (length(from) == 1 || abs(from[1] - from[2]) < 1e-06) return(mean(to)) : 
  missing value where TRUE/FALSE needed

这是由负无穷大问题引起的。

当您使用比例变换时,将变换应用于数据,然后进行统计和排列,然后在逆变换(粗略)中标记比例。您可以通过自己打破计算来了解正在发生的事情。

DF <- ddply(diamonds, .(clarity, cut), summarise, n=length(clarity))
DF$log10n <- log10(DF$n)

给出了

> head(DF)
  clarity       cut   n   log10n
1      I1      Fair 210 2.322219
2      I1      Good  96 1.982271
3      I1 Very Good  84 1.924279
4      I1   Premium 205 2.311754
5      I1     Ideal 146 2.164353
6     SI2      Fair 466 2.668386

如果我们以正常方式绘制,我们得到预期的条形图:

ggplot(DF, aes(x=clarity, y=n, fill=cut)) + 
  geom_bar(stat="identity")

enter image description here

并缩放y轴会产生与使用未预先汇总的数据相同的问题。

ggplot(DF, aes(x=clarity, y=n, fill=cut)) +
  geom_bar(stat="identity") +
  scale_y_log10()

enter image description here

我们可以通过绘制计数的log10()值来了解问题是如何发生的。

ggplot(DF, aes(x=clarity, y=log10n, fill=cut)) +
  geom_bar(stat="identity")

enter image description here

这看起来就像scale_y_log10那样,但标签是0,5,10,...而不是10 ^ 0,10 ^ 5,10 ^ 10,......

因此,使用scale_y_log10进行计数,将它们转换为日志,堆叠这些日志,然后以反日志形式显示比例。但是,堆叠日志不是线性转换,因此您要求它执行的操作没有任何意义。

最重要的是,对数刻度上的堆积条形图没有多大意义,因为它们不能从0开始(条形的底部应该是),并且比较条形的部分是不合理的,因为它们的大小取决于它们在堆栈中的位置。改为考虑:

ggplot(diamonds, aes(x=clarity, y=..count.., colour=cut)) + 
  geom_point(stat="bin") +
  scale_y_log10()

enter image description here

或者如果你真的想要通常会给你的那些堆积酒吧的团体,你可以做以下事情:

ggplot(diamonds, aes(x=clarity, y=..count..)) + 
  geom_point(aes(colour=cut), stat="bin") +
  geom_point(stat="bin", colour="black") +
  scale_y_log10()

enter image description here