创建堆叠条形图,其中每个堆栈都缩放为总和为 100%

Posted

技术标签:

【中文标题】创建堆叠条形图,其中每个堆栈都缩放为总和为 100%【英文标题】:Create stacked barplot where each stack is scaled to sum to 100% 【发布时间】:2012-03-22 17:33:05 【问题描述】:

我有一个这样的data.frame:

df <- read.csv(text = "ONE,TWO,THREE
                       23,234,324
                       34,534,12
                       56,324,124
                       34,234,124
                       123,534,654")

我想制作一个看起来像这样的百分比条形图(在 LibreOffice Calc 中制作):

因此,条形应该标准化,以便所有堆栈具有相同的高度并且总和为 100%。到目前为止,我所能得到的只是一个堆叠的条形图(不是百分比),使用:

barplot(as.matrix(df))

有什么帮助吗?

【问题讨论】:

【参考方案1】:

您只需将每个元素除以其列中值的总和即可。

这样做就足够了:

data.perc <- apply(data, 2, function(x)x/sum(x))

请注意,第二个参数告诉apply 将提供的函数应用于列(使用 1 您会将其应用于行)。然后,匿名函数每次传递一个数据列。

【讨论】:

您好,这并没有调整我的数据,rowSums(data.perc) 不是每行 1。相反,我使用了这个:data.perc &lt;- apply(data, 2, function(x)x/(apply(data,1,sum))) 您是否有 NA 或零和线?否则我不太明白为什么那行不通......【参考方案2】:

prop.table 是一种很好的获取表格比例的友好方式。

m <- matrix(1:4,2)

 m
     [,1] [,2]
[1,]    1    3
[2,]    2    4

留空边距为您提供整个表格的比例

 prop.table(m, margin=NULL)
     [,1] [,2]
[1,]  0.1  0.3
[2,]  0.2  0.4

给它 1 给你行比例

 prop.table(m, 1)
      [,1]      [,2]
[1,] 0.2500000 0.7500000
[2,] 0.3333333 0.6666667

而2是列比例

 prop.table(m, 2)
          [,1]      [,2]
[1,] 0.3333333 0.4285714
[2,] 0.6666667 0.5714286

【讨论】:

【参考方案3】:

这是一个使用 ggplot 包(版本 3.x)的解决方案,以及您目前所获得的解决方案。

我们将geom_barposition 参数设置为position = "fill"。如果要使用position_fill() 的参数(vjustreverse),也可以使用position = position_fill()

请注意,您的数据是“宽”格式,而ggplot2 要求它是“长”格式。因此,我们首先需要gather 数据。

library(ggplot2)
library(dplyr)
library(tidyr)

dat <- read.table(text = "    ONE TWO THREE
1   23  234 324
2   34  534 12
3   56  324 124
4   34  234 124
5   123 534 654",sep = "",header = TRUE)

# Add an id variable for the filled regions and reshape
datm <- dat %>% 
  mutate(ind = factor(row_number())) %>%  
  gather(variable, value, -ind)

ggplot(datm, aes(x = variable, y = value, fill = ind)) + 
    geom_bar(position = "fill",stat = "identity") +
    # or:
    # geom_bar(position = position_fill(), stat = "identity") 
    scale_y_continuous(labels = scales::percent_format())

【讨论】:

melt() 属于哪个包?是reshape2吗? 是的;我很抱歉。这么长时间 ggplot2 自己加载这些包,我已经生锈了。 我尝试使用 reshape 包中的 melt 并收到以下错误:“Scale$labels(breaks) 中的错误:未使用的参数 (s) (breaks)”我想知道是不是因为我我正在从 csv 读取数据。 @JulioDiaz 嗯。很难说发生了什么,特别是如果您正在使用的数据看起来与您问题中的示例不完全相同。我会确保所有软件包都是最新的,并且您使用的是 R 2.14.2(我必须升级到 2.14.2 才能让 ggplot 0.9.0 中的一些东西正常工作)。 对于那些在 2018 年之后使用此功能的用户,请将“labels = percent_format()”替换为“scales::percent”。【参考方案4】:

Chris Beeley 是正确的,您只需要按列的比例。使用您的数据是:

 your_matrix<-( 
               rbind(
                       c(23,234,324), 
                       c(34,534,12), 
                       c(56,324,124), 
                       c(34,234,124),
                       c(123,534,654)
                    )
                )

 barplot(prop.table(your_matrix, 2) )

给予:

【讨论】:

这应该是公认的答案。真的很简单,很简单。 @kboom 它不使用ggplot2,因此 OP 标记了他的问题

以上是关于创建堆叠条形图,其中每个堆栈都缩放为总和为 100%的主要内容,如果未能解决你的问题,请参考以下文章

堆积条形图,按总计(值的总和)重新排序,而不是值 ggplot2 + dplyr

在Seaborn中绘制堆积条形图以显示聚类[重复]

如何将标签添加到堆叠条形图

堆叠的条形图意外地用条形高度的总和进行了注释

ggplot2 - 带有堆栈和闪避的条形图

D3:如何在单个图表中处理缩放和工具提示?