2016-04-07 35 views
0

我想用下面的示例數據d構造一個堆積條形圖(或箭頭圖),最好使用ggplot2,對於每個id帶有一些負值和排序類別的堆疊條形圖

特點是,我想堆棧跟隨列訂購v0第一,z1第二和第三z2(數據是在寬格式)。但請注意,z2有一些負值。所以它應該以某種方式由箭頭或其他東西表示,從堆棧頂部向下(或向上,取決於z3的值)。

有沒有辦法做到這一點?

d <- data.frame(
    id=c('AAA','BBB','CCC','DDD','EEE','FFF'), 
    v0 =c(50 , 60 , 40 , 50 , 70 ,40), 
    z1 =c(20 , 15 , 5 , 40 , 5 , 40), 
    z2 =c(-10 , 5 , 10 ,-20 , 15 ,-15) 
) 

#normaly people transform the data to long format: 
d %>% gather(ef_type, value,v0:d2) %>% 
    ggplot(aes(...) + geom_bar(...) 

OBS:注意,這是從答案this related question,其中,所述列的順序並不重要不同,負值在y軸的負部分表示。

EDIT1:基於@fanli答案波紋管我嘗試下面的代碼:

d %>% select(id,v0,z1) %>% gather(ef_type, value,v0:z1) -> df 
d %>% mutate(z2_start=v0+z1,z2_end=v0+z1+z2) %>% select(id,z2_start,z2_end) -> df2 

ggplot(df, aes(x=id,y=value,fill=ef_type))+ geom_bar(stat = "identity") + 
    + geom_segment(data=df2, aes(x=id, xend=id, y=z2_start, yend=z2_end), arrow = arrow(length = unit(0.02, "npc"))) 

#which results in the error: 
Error: ggplot2 doesn't know how to deal with data of class uneval 

回答

4

您正在尋找這樣的事情?

df <- melt(d) 
df$absvalue <- abs(df$value) 
df <- ddply(df, .(id), transform, pos = 
    ifelse(value<0, cumsum(absvalue)-(0.4 * absvalue), 
    cumsum(absvalue)-(0.6 * absvalue))) 
df <- ddply(df, .(id), transform, pos2 = 
    ifelse(value>0, cumsum(absvalue)-(0.4 * absvalue), 
    cumsum(absvalue)-(0.6 * absvalue))) 
ggplot(df, aes(x=id,y=absvalue,group=variable,fill=variable)) 
    + geom_bar(stat="identity", position="stack") 
    + geom_segment(aes(x=id, xend=id, y=pos, yend=pos2), arrow = arrow(length = unit(0.02, "npc"))) 

enter image description here

您可以用箭頭的位置/數量/尺寸播放,但geom_segment似乎是一個可能性,你想要什麼。

編輯:基於澄清所需的輸出的:

DF < - 融化(d)

ggplot(subset(df, variable!="z2"), aes(x=id,y=value,group=variable,fill=variable)) 
+ geom_bar(stat="identity", position="stack") + geom_segment(data=d, 
    aes(x=id, xend=id, y=v0+z1, yend=v0+z1+z2), arrow = arrow(length = unit(0.02, "npc")), inherit.aes=F) 

enter image description here

編輯2:使用scale_fill_manualscale_color_manual定製圖例鍵:

d <- data.frame(
    id=c('AAA','BBB','CCC','DDD','EEE','FFF'), 
    v0 =c(50 , 60 , 40 , 50 , 70 ,40), 
    z1 =c(20 , 15 , 5 , 40 , 5 , 40), 
    z2 =c(-10 , 5 , 10 ,-20 , 15 ,-15) 
) 
d$cc <- "effect B" 
df <- melt(d) 
ggplot(subset(df, variable!="z2"), aes(x=id,y=value,group=variable,fill=variable)) + geom_bar(stat="identity", position="stack") + geom_segment(data=d, aes(x=id, xend=id, y=v0+z1, yend=v0+z1+z2, color=cc), arrow = arrow(length = unit(0.02, "npc")), inherit.aes=F) + scale_color_manual(values="black") + scale_fill_manual(values=c("skyblue", "red"), labels=c("base level", "effect A")) 
+0

涼爽。這或多或少是我想要的。 Cathegory z2不應該顯示爲條形,只能作爲箭頭,從「v0 + z1」開始,以「v0 + z1-z2」結尾 – LucasMation

+0

這太棒了!該圖表剩下的唯一問題是,爲圖例賦予某些值會很好。可以說標籤是v0:「base level」; z1:「效果A」; z2(箭頭)「效果B」。這個ne能否以某種方式包含在圖例中? – LucasMation

+0

你在使用reshape2 :: melt嗎?我嘗試複製您的代碼在我的電腦,但我得到一個錯誤:錯誤+ geom_bar(統計=「身份」,位置=「堆棧」): 一元運算符 – LucasMation