按带 ggplot/plyr 的条形段总和对条形图重新排序
reorder barchart by sum of bar segments with ggplot/plyr
我需要将以下堆叠条形图中的 11 个条形图按每个条形图的前两个段的总和重新排序,即按(红色+绿色)段排序在情节中。
> 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 表示 "bar label position" 并且是图中各个数字的位置。)但是绘制此 "sorted" 数据框会导致与上述相同的图。我不明白要更改哪些信息才能更改ItemQ列的绘图顺序。
q1m.bl.s <- arrange(q1m.bl, ItemA, desc(blpos))
ggplot(q1m.bl.s, ....
最好的方法是什么?在绘图之前,我应该 操纵 df (使用 ddply/arrange/reorder/etc.)吗?因为我倾向于认为这是一个演示问题,应该在 inside ggplot 中完成。这有关系吗?我在 SO 上发现的 "ggplot ordered barchart" 问题似乎同时使用了这两种方法;但是 none 我发现指的是堆积条 段 并使用因子数据...因此出现了这个新问题。
非常感谢您的开导!
这都是关于重新排序 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)
那么您应该能够 运行 完全按照您提供的代码生成:
编辑(digisus):konvas,我只是重新添加你的第一个答案,显示了 ddply 的使用,因为即使我对 it/do 没有完全理解它感到不舒服,我相信其他人可以受益从中。 :-) 因此,在您允许的情况下,我将其重新发布在这里:
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)
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
的内部顺序相同的顺序。因此,要影响绘制的顺序,您必须编写一个函数,该函数 returns 预期的顺序 - 取决于任何事实和值 - 并使用它来创建因子 fac
- 然后使用这个正确排序的函数绘图的因素。
也可以通过应用 reorder() 对因子的水平重新排序来达到预期的结果。
我需要将以下堆叠条形图中的 11 个条形图按每个条形图的前两个段的总和重新排序,即按(红色+绿色)段排序在情节中。
> 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 表示 "bar label position" 并且是图中各个数字的位置。)但是绘制此 "sorted" 数据框会导致与上述相同的图。我不明白要更改哪些信息才能更改ItemQ列的绘图顺序。
q1m.bl.s <- arrange(q1m.bl, ItemA, desc(blpos))
ggplot(q1m.bl.s, ....
最好的方法是什么?在绘图之前,我应该 操纵 df (使用 ddply/arrange/reorder/etc.)吗?因为我倾向于认为这是一个演示问题,应该在 inside ggplot 中完成。这有关系吗?我在 SO 上发现的 "ggplot ordered barchart" 问题似乎同时使用了这两种方法;但是 none 我发现指的是堆积条 段 并使用因子数据...因此出现了这个新问题。
非常感谢您的开导!
这都是关于重新排序 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)
那么您应该能够 运行 完全按照您提供的代码生成:
编辑(digisus):konvas,我只是重新添加你的第一个答案,显示了 ddply 的使用,因为即使我对 it/do 没有完全理解它感到不舒服,我相信其他人可以受益从中。 :-) 因此,在您允许的情况下,我将其重新发布在这里:
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)
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
的内部顺序相同的顺序。因此,要影响绘制的顺序,您必须编写一个函数,该函数 returns 预期的顺序 - 取决于任何事实和值 - 并使用它来创建因子 fac
- 然后使用这个正确排序的函数绘图的因素。
也可以通过应用 reorder() 对因子的水平重新排序来达到预期的结果。