使用 ggplot2 对堆积条形图中的分类数据进行排序

发布于 2024-12-01 05:22:28 字数 4413 浏览 0 评论 0原文

我有一个包含以下条目的矩阵:

MilDis <- data.frame(
  hhDomMil = c(
    "HED", "ETB", "HED", "ETB", "PER", "BUM", "EXP", "TRA", "TRA", "PMA", "MAT",
    "MAT", "KON", "ETB", "PMA", "PMA", "HED", "BUM", "BUM", "HED", "PMA", "PMA",
    "HED", "TRA", "BUM", "EXP", "BUM", "PMA", "ETB", "MAT", "ETB", "ETB", "KON",
    "MAT", "TRA", "BUM", "BUM", "TRA", "TRA", "PMA", "PMA", "PMA", "MAT", "ETB",
    "TRA", "BUM", "TRA", "MAT", "BUM", "ETB", "TRA", "TRA", "BUM", "KON", "ETB",
    "ETB", "ETB", "BUM", "KON", "ETB", "ETB", "PMA", "TRA", "PER", "PER", "MAT",
    "HED", "KON", "TRA", "TRA", "TRA", "EXP", "TRA", "BUM", "MAT", "MAT", "TRA",
    "PMA", "HED", "PER", "TRA", "PER", "EXP", "PER", "BUM", "KON", "BUM", "ETB",
    "ETB", "TRA", "PER", "ETB", "KON", "KON", "BUM", "ETB", "BUM", "MAT", "BUM",
    "KON", "KON", "ETB", "MAT", "KON", "PER", "ETB", "ETB", "KON", "PMA", "PER",
    "HED", "HED", "PMA", "MAT", "PMA", "PER", "PMA", "TRA", "TRA", "MAT", "BUM",
    "BUM", "KON", "ETB", "ETB", "ETB", "PMA", "TRA", "TRA", "PMA", "PER", "KON",
    "PER", "BUM", "KON", "ETB", "ETB", "BUM", "TRA", "ETB", "PMA", "HED", "MAT",
    "TRA", "BUM", "PMA", "BUM", "ETB", "TRA", "TRA", "TRA", "PER", "EXP", "HED",
    "BUM", "EXP", "HED", "BUM", "MAT", "DDR", "BUM", "MAT", "KON", "HED", "HED",
    "TRA", "BUM", "PMA", "PMA", "PMA", "KON", "KON", "MAT", "ETB", "MAT", "TRA",
    "MAT", "ETB", "ETB", "TRA", "MAT", "ETB", "TRA", "HED", "BUM", "MAT", "TRA",
    "PMA", "BUM", "BUM", "EXP", "ETB", "EXP", "EXP", "MAT", "TRA", "KON", "BUM",
    "BUM", "HED"
  ),
  kclust = c(
    1L, 2L, 15L, 4L, 5L, 6L, 5L, 7L, 8L, 5L, 6L, 5L, 11L, 6L, 5L,
    1L, 9L, 10L, 2L, 1L, 9L, 8L, 4L, 11L, 14L, 5L, 8L, 11L, 12L,
    5L, 5L, 14L, 15L, 2L, 10L, 6L, 8L, 4L, 6L, 8L, 14L, 14L, 16L,
    10L, 5L, 1L, 12L, 17L, 12L, 16L, 16L, 5L, 10L, 14L, 8L, 19L,
    5L, 4L, 4L, 14L, 2L, 14L, 9L, 7L, 1L, 14L, 4L, 15L, 18L, 16L,
    9L, 14L, 6L, 14L, 12L, 11L, 4L, 7L, 8L, 12L, 9L, 16L, 2L, 6L,
    15L, 1L, 1L, 3L, 14L, 5L, 5L, 9L, 14L, 6L, 5L, 14L, 15L, 2L,
    14L, 2L, 1L, 8L, 5L, 10L, 1L, 1L, 16L, 5L, 2L, 9L, 9L, 1L, 12L,
    10L, 1L, 4L, 1L, 9L, 8L, 8L, 5L, 10L, 1L, 10L, 2L, 6L, 15L, 2L,
    2L, 10L, 5L, 6L, 10L, 19L, 19L, 6L, 5L, 6L, 7L, 7L, 8L, 5L, 16L,
    5L, 6L, 6L, 1L, 10L, 12L, 4L, 7L, 19L, 7L, 8L, 16L, 10L, 5L,
    16L, 12L, 7L, 7L, 19L, 4L, 6L, 1L, 15L, 7L, 8L, 16L, 4L, 10L,
    15L, 11L, 10L, 1L, 10L, 17L, 1L, 2L, 1L, 14L, 8L, 8L, 14L, 10L,
    8L, 6L, 6L, 8L, 5L, 7L, 5L, 1L, 5L, 7L, 9L, 2L, 1L, 9L, 14L
  ),
  order = c(
    9, 1, 9, 1, 3, 7, 10, 5, 5, 2, 8, 8, 4, 1, 2, 2, 9, 7, 7, 9, 2, 2, 9, 5, 7,
    10, 7, 2, 1, 8, 1, 1, 4, 8, 5, 7, 7, 5, 5, 2, 2, 2, 8, 1, 5, 7, 5, 8, 7, 1, 5,
    5, 7, 4, 1, 1, 1, 7, 4, 1, 1, 2, 5, 3, 3, 8, 9, 4, 5, 5, 5, 10, 5, 7, 8, 8, 5,
    2, 9, 3, 5, 3, 10, 3, 7, 4, 7, 1, 1, 5, 3, 1, 4, 4, 7, 1, 7, 8, 7, 4, 4, 1, 8,
    4, 3, 1, 1, 4, 2, 3, 9, 9, 2, 8, 2, 3, 2, 5, 5, 8, 7, 7, 4, 1, 1, 1, 2, 5, 5,
    2, 3, 4, 3, 7, 4, 1, 1, 7, 5, 1, 2, 9, 8, 5, 7, 2, 7, 1, 5, 5, 5, 3, 10, 9, 7,
    10, 9, 7, 8, 6, 7, 8, 4, 9, 9, 5, 7, 2, 2, 2, 4, 4, 8, 1, 8, 5, 8, 1, 1, 5, 8,
    1, 5, 9, 7, 8, 5, 2, 7, 7, 10, 1, 10, 10, 8, 5, 4, 7, 7, 9
  )
)

我想创建一个像这样的堆叠条形图 Barplot

唯一的问题是,我希望堆栈的顺序适合这个(ETB,PMA,PER,KON,TRA,DDR,BUM,MAT,HED,EXP) - 矩阵中的顺序号,我有还有一些审美问题。我在这里寻找解决方案,但没有一个排序建议对我有用......:-\

  1. 如何绘制这样的有序图?
  2. 如何设置 x 以使每个条形都“位于”一个数字上?
  3. 我如何分隔条形 - 这里我尝试用白色边框......?
  4. 如何打印 x 中的所有 kclust 数字?

非常感谢您的帮助! Dominik


更新

这是我用来绘制绘图的代码:

mycols <- c('#FFFD00', '#97CB00', '#3168FF', '#FF0200', '#FB02FE', \
'#CCFCCC', '#FE9900', '#98CBF8', '#00CCFF', '#00FD03') # Set milieu colors


ggplot(MilDis) +
 geom_bar(aes(kclust, fill=factor(hhDomMil), \
 colour=mycols), position='fill', binwidth=1, colour='white') +
 scale_fill_manual(values = mycols)

更新 2:

这就是我现在的做法:

    mycols <- c('#3168FF', '#00CCFF', '#98CBF8', '#CCFCCC', '#00FD03',\
   '#97CB00', '#FFFD00', '#FE9900', '#FB02FE', '#FF0200') # Set milieu colors
   
    ggplot(MilDis) +
      geom_bar(aes(factor(kclust), fill=reorder(hhDomMil,order)),\
      position='fill') +
      scale_fill_manual(values = mycols)

结果如下:

Image

谢谢大家的帮助!

I have a matrix with the following entries:

MilDis <- data.frame(
  hhDomMil = c(
    "HED", "ETB", "HED", "ETB", "PER", "BUM", "EXP", "TRA", "TRA", "PMA", "MAT",
    "MAT", "KON", "ETB", "PMA", "PMA", "HED", "BUM", "BUM", "HED", "PMA", "PMA",
    "HED", "TRA", "BUM", "EXP", "BUM", "PMA", "ETB", "MAT", "ETB", "ETB", "KON",
    "MAT", "TRA", "BUM", "BUM", "TRA", "TRA", "PMA", "PMA", "PMA", "MAT", "ETB",
    "TRA", "BUM", "TRA", "MAT", "BUM", "ETB", "TRA", "TRA", "BUM", "KON", "ETB",
    "ETB", "ETB", "BUM", "KON", "ETB", "ETB", "PMA", "TRA", "PER", "PER", "MAT",
    "HED", "KON", "TRA", "TRA", "TRA", "EXP", "TRA", "BUM", "MAT", "MAT", "TRA",
    "PMA", "HED", "PER", "TRA", "PER", "EXP", "PER", "BUM", "KON", "BUM", "ETB",
    "ETB", "TRA", "PER", "ETB", "KON", "KON", "BUM", "ETB", "BUM", "MAT", "BUM",
    "KON", "KON", "ETB", "MAT", "KON", "PER", "ETB", "ETB", "KON", "PMA", "PER",
    "HED", "HED", "PMA", "MAT", "PMA", "PER", "PMA", "TRA", "TRA", "MAT", "BUM",
    "BUM", "KON", "ETB", "ETB", "ETB", "PMA", "TRA", "TRA", "PMA", "PER", "KON",
    "PER", "BUM", "KON", "ETB", "ETB", "BUM", "TRA", "ETB", "PMA", "HED", "MAT",
    "TRA", "BUM", "PMA", "BUM", "ETB", "TRA", "TRA", "TRA", "PER", "EXP", "HED",
    "BUM", "EXP", "HED", "BUM", "MAT", "DDR", "BUM", "MAT", "KON", "HED", "HED",
    "TRA", "BUM", "PMA", "PMA", "PMA", "KON", "KON", "MAT", "ETB", "MAT", "TRA",
    "MAT", "ETB", "ETB", "TRA", "MAT", "ETB", "TRA", "HED", "BUM", "MAT", "TRA",
    "PMA", "BUM", "BUM", "EXP", "ETB", "EXP", "EXP", "MAT", "TRA", "KON", "BUM",
    "BUM", "HED"
  ),
  kclust = c(
    1L, 2L, 15L, 4L, 5L, 6L, 5L, 7L, 8L, 5L, 6L, 5L, 11L, 6L, 5L,
    1L, 9L, 10L, 2L, 1L, 9L, 8L, 4L, 11L, 14L, 5L, 8L, 11L, 12L,
    5L, 5L, 14L, 15L, 2L, 10L, 6L, 8L, 4L, 6L, 8L, 14L, 14L, 16L,
    10L, 5L, 1L, 12L, 17L, 12L, 16L, 16L, 5L, 10L, 14L, 8L, 19L,
    5L, 4L, 4L, 14L, 2L, 14L, 9L, 7L, 1L, 14L, 4L, 15L, 18L, 16L,
    9L, 14L, 6L, 14L, 12L, 11L, 4L, 7L, 8L, 12L, 9L, 16L, 2L, 6L,
    15L, 1L, 1L, 3L, 14L, 5L, 5L, 9L, 14L, 6L, 5L, 14L, 15L, 2L,
    14L, 2L, 1L, 8L, 5L, 10L, 1L, 1L, 16L, 5L, 2L, 9L, 9L, 1L, 12L,
    10L, 1L, 4L, 1L, 9L, 8L, 8L, 5L, 10L, 1L, 10L, 2L, 6L, 15L, 2L,
    2L, 10L, 5L, 6L, 10L, 19L, 19L, 6L, 5L, 6L, 7L, 7L, 8L, 5L, 16L,
    5L, 6L, 6L, 1L, 10L, 12L, 4L, 7L, 19L, 7L, 8L, 16L, 10L, 5L,
    16L, 12L, 7L, 7L, 19L, 4L, 6L, 1L, 15L, 7L, 8L, 16L, 4L, 10L,
    15L, 11L, 10L, 1L, 10L, 17L, 1L, 2L, 1L, 14L, 8L, 8L, 14L, 10L,
    8L, 6L, 6L, 8L, 5L, 7L, 5L, 1L, 5L, 7L, 9L, 2L, 1L, 9L, 14L
  ),
  order = c(
    9, 1, 9, 1, 3, 7, 10, 5, 5, 2, 8, 8, 4, 1, 2, 2, 9, 7, 7, 9, 2, 2, 9, 5, 7,
    10, 7, 2, 1, 8, 1, 1, 4, 8, 5, 7, 7, 5, 5, 2, 2, 2, 8, 1, 5, 7, 5, 8, 7, 1, 5,
    5, 7, 4, 1, 1, 1, 7, 4, 1, 1, 2, 5, 3, 3, 8, 9, 4, 5, 5, 5, 10, 5, 7, 8, 8, 5,
    2, 9, 3, 5, 3, 10, 3, 7, 4, 7, 1, 1, 5, 3, 1, 4, 4, 7, 1, 7, 8, 7, 4, 4, 1, 8,
    4, 3, 1, 1, 4, 2, 3, 9, 9, 2, 8, 2, 3, 2, 5, 5, 8, 7, 7, 4, 1, 1, 1, 2, 5, 5,
    2, 3, 4, 3, 7, 4, 1, 1, 7, 5, 1, 2, 9, 8, 5, 7, 2, 7, 1, 5, 5, 5, 3, 10, 9, 7,
    10, 9, 7, 8, 6, 7, 8, 4, 9, 9, 5, 7, 2, 2, 2, 4, 4, 8, 1, 8, 5, 8, 1, 1, 5, 8,
    1, 5, 9, 7, 8, 5, 2, 7, 7, 10, 1, 10, 10, 8, 5, 4, 7, 7, 9
  )
)

I want to create a stacked bar plot like this one Barplot.

The only problem is, that I would like to have the order of the stacks to fit this (ETB,PMA,PER,KON,TRA,DDR,BUM,MAT,HED,EXP) - the order numbers in the matrix and I have also some aesthetic problems. I searched for a solution here but none of the ordering suggestions worked for me... :-\

  1. How do I plot such a ordered plot?
  2. How do I set up x so that each bar is "on" one number?
  3. How do I seperate the bars - here I tried that with a white border...?
  4. How do I print all kclust numbers in x?

Thanks a lot for your help!
Dominik


UPDATE

Here is the code I used to draw my plot:

mycols <- c('#FFFD00', '#97CB00', '#3168FF', '#FF0200', '#FB02FE', \
'#CCFCCC', '#FE9900', '#98CBF8', '#00CCFF', '#00FD03') # Set milieu colors


ggplot(MilDis) +
 geom_bar(aes(kclust, fill=factor(hhDomMil), \
 colour=mycols), position='fill', binwidth=1, colour='white') +
 scale_fill_manual(values = mycols)

UPDATE 2:

That's how I did it now:

    mycols <- c('#3168FF', '#00CCFF', '#98CBF8', '#CCFCCC', '#00FD03',\
   '#97CB00', '#FFFD00', '#FE9900', '#FB02FE', '#FF0200') # Set milieu colors
   
    ggplot(MilDis) +
      geom_bar(aes(factor(kclust), fill=reorder(hhDomMil,order)),\
      position='fill') +
      scale_fill_manual(values = mycols)

With this result:

Image

Thank you all for your help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

心房的律动 2024-12-08 05:22:29

我看到您的数据框中有一个 order 列,我收集的就是您的订单。因此你可以简单地这样做。

p0 = qplot(factor(kclust), fill = reorder(hhDomMil, order), position = 'fill', 
       data = df1)

以下是此代码的元素,可解决您的问题

  1. 如何绘制这样的有序图? reorder
  2. 如何设置 x 以使每个条形都“位于”一个数字上? factor(kclust)
  3. 如何分离条形?
  4. 如何打印 x 中的所有 kclust 数字? factor(kclust)

我记得从你之前的问题中,hhDomMil 对应于不同的组,我怀疑你的排序遵循分组。在这种情况下,您可能希望使用该信息来选择调色板,以便更轻松地遵循图表。这是一种方法。

mycols = c(brewer.pal(3, 'Oranges'), brewer.pal(3, 'Greens'), 
           brewer.pal(2, 'Blues'), brewer.pal(2, 'PuRd'))

p0 + scale_fill_manual(values = mycols)

在此处输入图像描述

I see that you have an order column in your data frame which I gather is your order. Hence you can simply do.

p0 = qplot(factor(kclust), fill = reorder(hhDomMil, order), position = 'fill', 
       data = df1)

Here are the elements of this code that take care of your questions

  1. How do I plot such a ordered plot? reorder
  2. How do I set up x so that each bar is "on" one number? factor(kclust)
  3. How do I seperate the bars?
  4. How do I print all kclust numbers in x? factor(kclust)

I remember from a previous question of yours that the hhDomMil corresponded to different groups, and I suspect your ordering follows the grouping. In that case, you might want to use that information to choose a color palette that makes it simpler to follow the graph. Here is one way to do it.

mycols = c(brewer.pal(3, 'Oranges'), brewer.pal(3, 'Greens'), 
           brewer.pal(2, 'Blues'), brewer.pal(2, 'PuRd'))

p0 + scale_fill_manual(values = mycols)

enter image description here

流年已逝 2024-12-08 05:22:29

通过在将数据传递给 ggplot() 之前正确设置数据格式,可以轻松解决此问题。关键是显式设置 hhDomMil 因子的级别。假设您的数据位于 dat 中:

dat <- transform(dat, hhDomMil = factor(hhDomMil,
                                        levels = c("ETB", "PMA", "PER", "KON",
                                                   "TRA", "DDR", "BUM", "MAT",
                                                   "HED", "EXP")))

这会将 hhDomMil 修复为 dat 内的一个因素,并且 将级别设置为您想要的顺序:

> head(dat$hhDomMil)
[1] HED ETB HED ETB PER BUM
Levels: ETB PMA PER KON TRA DDR BUM MAT HED EXP

注意当 R 强制 hhDomMil 为一个因子时发生了什么:

> head(factor(as.character(dat$hhDomMil)))
[1] HED ETB HED ETB PER BUM
Levels: BUM DDR ETB EXP HED KON MAT PER PMA TRA

默认是按字母顺序对级别进行排序,这就是绘图出现的原因正如你所展示的那样。

我能给出的最好建议是,首先正确设置数据格式,然后再尝试绘制它 - 不要依赖自动或即时转换来获得适合您的数据;必然不会是你想要的。

The answer to this is easily solved by getting your data formatted correctly before passing it to ggplot(). The key is to explicitly set the levels of the hhDomMil factor. Assuming your data are in dat:

dat <- transform(dat, hhDomMil = factor(hhDomMil,
                                        levels = c("ETB", "PMA", "PER", "KON",
                                                   "TRA", "DDR", "BUM", "MAT",
                                                   "HED", "EXP")))

That fixes hhDomMil as a factor in place inside dat, and sets the levels to be in the order you wanted:

> head(dat$hhDomMil)
[1] HED ETB HED ETB PER BUM
Levels: ETB PMA PER KON TRA DDR BUM MAT HED EXP

Notice what is happing when R coerces hhDomMil to a factor:

> head(factor(as.character(dat$hhDomMil)))
[1] HED ETB HED ETB PER BUM
Levels: BUM DDR ETB EXP HED KON MAT PER PMA TRA

The default is to sort the levels alphabetically, which is why the plot is coming out as you show.

The best advice I can give, is to get your data correctly formatted first and only then try to plot it - don't rely on automatic or on-the-fly conversion to get this right for you; inevitably it won't be what you want.

感情旳空白 2024-12-08 05:22:29

如果您将 hhDomMil 重新调整为这样的因素:

o<-c("ETB" "PMA" "PER" "KON" "TRA" "DDR" "BUM" "MAT" "HED" "EXP")
d$hh<-factor(d$hhDomMil,levels=o)

那么您的绘图将按照您喜欢的顺序排列:

ggplot(d,(aes(x=kclust, fill=hh))) +geom_bar(position="fill")

If you relevel your hhDomMil as a factor like this:

o<-c("ETB" "PMA" "PER" "KON" "TRA" "DDR" "BUM" "MAT" "HED" "EXP")
d$hh<-factor(d$hhDomMil,levels=o)

then your plot will be in the order you like:

ggplot(d,(aes(x=kclust, fill=hh))) +geom_bar(position="fill")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文