2012-02-29 144 views
15

我遇到了一個有趣的問題,使用ggplot進行縮放。我有一個數據集,我可以使用默認的線性比例進行繪圖,但是當我使用scale_y_log10()時,數字就會消失。這裏是一些示例代碼和兩張圖片。請注意,線性刻度的最大值爲〜700,而對數刻度的結果爲10^8。我告訴你,整個數據集只有大約8000條目,所以有些東西是不對的。ggplot scale_y_log10()問題

我想這個問題與我的數據集的結構和裝箱有關,因爲我無法在像「鑽石」這樣的常見數據集上覆制此錯誤。但是我不確定排除故障的最佳方法。

感謝, 扎克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") 

UPDATE:

行號都沒有問題。這裏使用相同的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

回答

24

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

+1

謝謝Brian,我很感謝你的詳細解釋。您也可以使用geom_bar(position =「dodge」)(答案由Winston Chang提供) – zach 2012-02-29 22:05:58

+0

爲了更深入地瞭解這裏發生的事情,堆積的條形圖通常會給出一個與計數總和相等的高度。但是,sum(log(counts))相當於log(product(counts))。換句話說,你會看到酒吧的高度,就像你把這些數字放在一起。 – Brian 2016-10-19 18:56:25