Create stacked barplot where each stack is scaled to sum to 100%

我有个数据框,像这样:

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

我想制作一个百分比条形图,看起来像这样(使用 LibreOffice Calc 制作) : enter image description here

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

barplot(as.matrix(df))

有人帮忙吗?

139578 次浏览

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

这样做应该足够了:

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

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

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

这里有一个使用 ggplot软件包(版本3.x)的解决方案。

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

请注意,您的数据是‘ wide’格式,而 ggplot2要求它是‘ long’格式。因此,我们首先需要 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())

example figure

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) )

给予:

enter image description here

另一种选择是使用带有 标度 _ y _ pct功能的 额外的鳞片包,它能够直接从您的数据创建一个百分比。首先,使用 pivot_longer将数据转换为较长的格式,并为每个组创建一个百分比列。下面是一个可重复的例子:

library(ggplot2)
library(dplyr)
library(tidyr)
# remotes::install_github("thomas-neitmann/scalesextra")
library(scalesextra)
df %>%
pivot_longer(cols=everything()) %>%
group_by(name) %>%
mutate(index = factor(row_number()),
pct = value/sum(value)*100) %>% # Create percentage values
ggplot(aes(x = factor(name, levels = unique(name)), y = pct, fill = index)) +
geom_col() +
scale_y_pct() +
labs(x = "Name")

创建于2022-08-23与 Reprex v2.0.2

For some extra info about this package and function check this 教程.