使用ggplot / plyr按条形段的总和重新排序条形图

时间:2015-03-17 13:29:09

标签: r ggplot2 plyr geom-bar

我需要在下面的堆积条形图中的11个条形图按每个条形图的前两个区段的总和重新排序,即按图中的(红色+绿色)线段排序。 / p>

> dput(q1m.bl)
structure(list(ItemA = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 
4L, 1L, 2L, 3L, 4L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 
1L, 2L, 3L, 4L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 
2L, 3L, 4L), .Label = c("sehr wichtig", "wichtig", "unwichtig", 
"keine Angabe"), class = "factor"), ItemQ = structure(c(1L, 1L, 
1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 5L, 5L, 5L, 
5L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 
10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L), .Label = c("PUSHERS_AA", 
"PUSHERS_COM", "PUSHERS_BED", "PUSHERS_SEC", "PUSHERS_STAB", 
"PUSHERS_COST", "PUSHERS_INNO", "PUSHERS_VAL", "PUSHERS_INDEP", 
"PUSHERS_STDS", "PUSHERS_SRC"), class = "factor"), Counts = c(1L, 
3L, 4L, 1L, 3L, 3L, 2L, 1L, 4L, 2L, 2L, 1L, 3L, 5L, 1L, 1L, 1L, 
6L, 1L, 5L, 1L, 2L, 1L, 1L, 1L, 6L, 1L, 2L, 6L, 1L, 2L, 4L, 2L, 
1L, 3L, 3L, 2L, 1L, 2L, 1L, 5L, 1L), blpos = c(0.111111111111111, 
0.444444444444444, 0.888888888888889, 1, 0.333333333333333,   0.666666666666667, 
0.888888888888889, 1, 0.444444444444444, 0.666666666666667, 0.888888888888889, 
1, 0.333333333333333, 0.888888888888889, 1, 0.111111111111111, 
0.222222222222222, 0.888888888888889, 1, 0.555555555555556, 0.666666666666667, 
0.888888888888889, 1, 0.111111111111111, 0.222222222222222, 0.888888888888889, 
1, 0.222222222222222, 0.888888888888889, 1, 0.222222222222222, 
0.666666666666667, 0.888888888888889, 1, 0.333333333333333, 0.666666666666667, 
0.888888888888889, 1, 0.222222222222222, 0.333333333333333, 0.888888888888889, 
1)), .Names = c("ItemA", "ItemQ", "Counts", "blpos"), row.names = c(NA, 
-42L), class = "data.frame")

情节......

ggplot(q1m.bl, aes(x = ItemQ, y = Counts, fill = ItemA)) + 
geom_bar(stat="identity", position="fill") + 
geom_text(aes(y = blpos, label = Counts), hjust = 1) +
theme(axis.text.x=element_text(angle=90, hjust = 0), text = element_text(size=10)) +
coord_flip()

呃,没有足够的重复点来嵌入图像。抱歉给你带来不便。情节在这里:http://i.stack.imgur.com/am0Ud.png

我玩了arrange()并且在检查了数据框本身后,我认为以下排序应该可以解决问题。 (注意:blpos表示"条形标签位置"并且是图中各种数字的位置。)但是绘制这个"排序"数据框导致与上面相同的图。我不明白要更改哪些信息来更改ItemQ列的绘图顺序。

q1m.bl.s <- arrange(q1m.bl, ItemA, desc(blpos))
ggplot(q1m.bl.s, ....

最好的方法是什么?我应该在绘图之前操纵df (使用ddply / arrange / reorder / etc.)吗?因为我倾向于认为这是一个演示问题,应该在内部 ggplot中完成。它甚至重要吗? &#34; ggplot订购了条形图&#34;我在SO上发现的问题似乎都使用了两种方法;但我发现没有一个是指堆积条并使用因子数据...因此这个新问题。

非常感谢你给我启发!

2 个答案:

答案 0 :(得分:1)

所有关于重新排序ItemQ变量的因子水平。

d <- subset(q1m.bl, ItemA %in% c("sehr wichtig", "wichtig"))
totals <- aggregate(d$Counts, list(ItemQ = d$ItemQ), sum)
ItemQ.order <- as.character(totals[order(-totals$x), ]$ItemQ)
q1m.bl$ItemQ <- factor(q1m.bl$ItemQ, levels = ItemQ.order)

然后你应该能够像你提供的那样完全运行代码,它会产生这样的代码:enter image description here

编辑(digisus):konvas,我只是重新添加你的第一个答案,显示使用ddply,因为即使我感觉不舒服/没有完全得到它,我相信其他人可以从中受益。 :-)所以,在你允许的情况下,我将它重新发布在这里:

library(plyr)
ItemQ.order <- q1m.bl %>%
  group_by(ItemQ) %>% 
  filter(ItemA %in% c("sehr wichtig", "wichtig")) %>% 
  summarise(total = sum(Counts)) %>%
  arrange(-total) %>% 
  select(ItemQ) %>%
  unlist %>%
  as.character

q1m.bl$ItemQ <- factor(q1m.bl$ItemQ, levels = ItemQ.order)

答案 1 :(得分:0)

library(ggplot2)

fac_ord <- function(seed){
  set.seed(seed)
  return(sample(letters[1:4]))
}

# this seed simulates arbitrary sortings
seed <- 2
fac_ord(seed)

val = c(1,2,3,4,2,2,2,2)
fac = factor(c("a","b","c","d","a","b","c","d"), 
             levels=fac_ord(seed), 
             labels=fac_ord(seed), 
             ordered=FALSE)
dif = c(rep("x",4),rep("y",4))

df  = data.frame(val = val, fac = fac)

ggplot(df, aes(x=fac, y=val, fill=dif)) + 
  geom_bar(stat="identity") + 
  labs(title = sprintf("seed = %d / %s", seed, paste(fac_ord(seed),collapse=",")))

如示例所示 - ggplot将在图中使用fac的相同排序作为fac的内部顺序。因此,为了影响绘制的顺序,你必须编写一个返回预期顺序的函数 - 依赖于任何事实和值 - 并使用它来创建因子fac - 然后使用这个适当排序的因子进行绘图

enter image description here

enter image description here

通过应用reorder()来重新排序因子水平,也可以达到预期的结果。