2016-10-03 485 views
0

我有類中排序的數據,如本文所述: https://www.r-bloggers.com/from-continuous-to-categorical/ 這可以更容易地查看哪些值是常見的。創建這些類之後,我想創建一個條形圖與不同類別,這是我做下面的示例代碼的頻率:geom_vline在x軸上的垂直線與分類數據:ggplot2

set.seed(1) 
df.v <- data.frame(val = rnorm(1000, mean(4, sd=2))) 
df.v$val.clss <- cut(df.v$val, seq(min(df.v$val), max(df.v$val), 1)) 
p1 <- ggplot(data = df.v)+ 
    geom_bar(aes(val.clss)) 
plot(p1) 

我想不通,就是如何準確添加之間的垂直線兩個4左右的線條,所以線條完全位於x軸值。 我發現了這篇文章,但這並沒有幫助我: How to get a vertical geom_vline to an x-axis of class date? 任何幫助表示讚賞。也許我太新以至於無法將解決方案適應於我的數據框架,如果是的話,請原諒這個問題。

回答

3

如果你知道你想要的行間去,你可以將他們的位置轉換爲數字(即它們映射到的因素)兩杆的標籤,然後傳遞:

myLoc <- 
    (which(levels(df.v$val.clss) == "(2.99,3.99]") + 
    which(levels(df.v$val.clss) == "(3.99,4.99]"))/
    2 


p1 + 
    geom_vline(aes(xintercept = myLoc)) 

如果它正在跳過組,你應該確保所有級別的因素都被繪製出來。當你有分級連續數據時,最好不要捨棄中間級別。

p1 + 
    geom_vline(aes(xintercept = myLoc)) + 
    scale_x_discrete(drop = FALSE) 

或者,您可以從數據中刪除丟失的水平一起(密謀之前和計算myLoc):

df.v <- droplevels(df.v) 

然後將只包括將被繪製。

作爲最後一個選項,您可以使用geom_histogram自動進行分箱,但將數據保留在原始比例上,這將使添加一條線更容易。

ggplot(df.v 
     , aes(val)) + 
    geom_histogram(binwidth = 1) + 
    geom_vline(xintercept = 4) 
+0

謝謝,這應該在理論上起作用。但是,當我將上面的示例代碼更改爲 'cut(df.v $ val,seq(min(df.v $ val),max(df.v $ val),0.2))' 因此有34個類,然後選擇16.5作爲xintercept,它離右側太遠了。 我不知道爲什麼,你能幫忙嗎?非常感謝。 那麼,我發現,當我使用'長度(水平(df.v $ val.clss))'它顯示我34,但是當我計算酒吧,我只能達到30酒吧。這似乎是我的問題的根源。 – rashid

+1

這很可能是由沒有值的類別引起的。 'ggplot'會默認放棄這些,這會影響劇情的級別。查看一些可選解決方案的編輯。但是請注意,應該謹慎使用'droplevels',因爲它通常不是連續數據的好主意。 –

+0

謝謝,'scale_x_discrete(drop = FALSE)'做了自動計算的竅門。我非常感謝幫助。 – rashid

2

你想要這樣的東西嗎?

p1 <- ggplot(data = df.v)+ 
    geom_bar(aes(val.clss)) + geom_vline(xintercept = 3.5, col='red', lwd=2) 
plot(p1) 

enter image description here

更通用的解決方案可能是這樣的:

df.v <- data.frame(val = rnorm(1000, mean=15, sd=4)) 
df.v$val.clss <- cut(df.v$val, seq(min(df.v$val), max(df.v$val), 1)) 

lvls <- levels(df.v$val.clss) 
lvls 
[1] "(2.97,3.97]" "(3.97,4.97]" "(4.97,5.97]" "(5.97,6.97]" "(6.97,7.97]" "(7.97,8.97]" "(8.97,9.97]" "(9.97,11]" "(11,12]"  "(12,13]"  
[11] "(13,14]"  "(14,15]"  "(15,16]"  "(16,17]"  "(17,18]"  "(18,19]"  "(19,20]"  "(20,21]"  "(21,22]"  "(22,23]"  
[21] "(23,24]"  "(24,25]"  "(25,26]"  "(26,27]"  "(27,28]"  "(28,29]"  "(29,30]"  

vline.level <- '(18,19]' # you want to draw line here, right before 18 

p1 <- ggplot(data = df.v)+ 
+ geom_bar(aes(val.clss)) + geom_vline(xintercept = which(lvls == vline.level) - 0.5, col='red', lwd=2) + 
+ theme(axis.text.x = element_text(angle=90, vjust = 0.5)) 
plot(p1) 

enter image description here

如果您想選擇最中間的水平,

length(lvls) 
#[1] 27 
# choose the middlemost level, since length(lvls) is odd in this case, the midpoint will be ceiling(length(lvls)/2) 
vline.level <- lvls[ceiling(length(lvls)/2)] 

p1 <- ggplot(data = df.v)+ 
    geom_bar(aes(val.clss)) + geom_vline(xintercept = which(lvls == vline.level) - 0.5, col='red', lwd=2) + 
    theme(axis.text.x = element_text(angle=90, vjust = 0.5)) 
plot(p1) 

enter image description here

+0

正是。但是,如何確定xintercept的值,特別是如果我有不同數量的類別?假設我有六個類別,然後我有10個類別。我如何計算xintercept的值?我有94個類別的案例,我發現工作的xintercept是43.5,遠遠沒有達到一半。 – rashid

+0

更新爲更通用的解決方案@rashid –

+0

非常感謝。但是線路仍然在右側,對嗎?左側15個酒吧,右側10個酒吧。我希望它在正確的中間,任何想法? – rashid