带有一些负值和有序类别的堆积条形图

时间:2016-04-07 15:11:39

标签: r ggplot2 bar-chart

我想为每个ggplot2构建一个堆积条形图(或箭头图),最好使用d,下面的示例数据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

1 个答案:

答案 0 :(得分: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&lt; - 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), 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"))