我有一个包含数字(百分比)和分类变量的数据框。我想生成一个堆积的条形图(使用ggplot2),并用数值变量对列(类别变量)进行排序。
我尝试过:
How to control ordering of stacked bar chart using identity on ggplot2
还有:
https://community.rstudio.com/t/a-tidy-way-to-order-stacked-bar-chart-by-fill-subset/5134
但是我不熟悉因素,我想了解更多。
# Reproduce a dummy dataset
perc <- c(11.89, 88.11, 2.56, 97.44, 5.96, 94.04, 6.74, 93.26)
names <- c('A', 'A', 'B', 'B', 'C', 'C', 'D', 'D')
df <- data.frame(class = rep(c(-1, 1), 4),
percentage = perc,
name = names)
# Plot
ggplot(df, aes(x = factor(name), y = percentage, fill = factor(class))) +
geom_bar(stat = "identity") +
scale_fill_discrete(name = "Class") +
xlab('Names')
此代码生成一个图,其条形由变量“名称”排序。我想按变量“百分比”对其进行排序。即使我手动订购数据框,结果图也一样。
答案 0 :(得分:1)
这里的问题是,给定类别(name
)的所有百分比实际上合计为100%。因此,按百分比排序(通常通过aes(x = reorder(name, percentage), y = percentage)
实现)在这里不起作用。
相反,您可能想按具有class = 1(或class = -1)的数据的百分比排序。这样做需要一些技巧:使用ifelse
为class == 1
中的行选择百分比。对于所有其他行,选择值0:
ggplot(df, aes(x = reorder(name, ifelse(class == 1, percentage, 0)), y = percentage, fill = factor(class))) +
geom_bar(stat = "identity") +
scale_fill_discrete(name = "Class") +
xlab('Names')
您可能只想执行reorder
指令以查看发生的情况:
reorder(df$name, ifelse(df$class == 1, df$percentage, 0))
# [1] A A B B C C D D
# attr(,"scores")
# A B C D
# 44.055 48.720 47.020 46.630
# Levels: A D C B
如您所见,您的姓名根据每个类别的平均百分比重新排序(默认情况下,reorder
使用均值; see its manual page for more details)。但是我们计算出的“均值”介于类别= 1的每个名称的百分比与值0(类别≠1的值)之间。
答案 1 :(得分:0)
它与Konrad Rudolph类似,我刚刚创建了一个因子水平,并使用它进行重新排序。这是我的解决方案:
x_order <- with(subset(df, class == -1), reorder(name, percentage))
df$name <- factor(df$name, levels = levels(x_order))
ggplot(df, aes(x = name, y = percentage, fill = factor(class))) +
geom_bar(stat = "identity") +
scale_x_discrete(breaks = levels(x_order))
答案 2 :(得分:0)
在绘制之前更改水平会为您完成
。lvlorder = order((df [df $ class ==-1,])$百分比,递减= T)
df $ name = factor(df $ name,level = level(df $ name)[lvlorder])