如何计算列中每个类别的份额?
How to calculate share per category within a column?
df = data.frame(week = as.factor(rep(c(1, 2), times = 5)),
name = as.factor(rep(LETTERS[1:5], times = 2)),
count = rpois(n = 10, lambda = 20))
> df
week name count
1 1 A 16
2 2 B 14
3 1 C 23
4 2 D 15
5 1 E 12
6 2 A 15
7 1 B 23
8 2 C 22
9 1 D 22
10 2 E 26
我想计算每个名字每周的计数份额。
起初我打算使用以下方法:
transform(df, week1_share = ifelse(week == "1", round((df$count / sum(df$count) * 100),2), NA))
transform(df, week2_share = ifelse(week == "2", round((df$count / sum(df$count) * 100),2), NA))
但是然后让每一列合并,最终将其作为标签放在条形图上,似乎效率太低了。一定有某种我还不知道的快速解决方案。
基本上我想做的是如下,但添加可能已按上述方法计算的份额百分比以在每个框中匹配。
ggplot(df, aes(reorder(week, -count),count, color = "white", group = name, fill = name))+
geom_bar(position = "stack", stat = "identity") +
scale_y_continuous(labels=comma)+
ggthemes::scale_color_tableau()
我不知道为什么重新排序功能经常在我身上失败。如果您有任何关于 desc 排序的技巧,请分享。
基于 R 的解决方案,使用 split
、unsplit
和 prop.table
将是:
df2 <- unsplit(lapply(split(df, df$week),
function(x){
x$prop <- prop.table(x$count)
x}
), df$week)
简而言之split
returns data.frames
根据第二个参数拆分的列表,unsplit 将拆分产生的列表组合在一起。
使用 data.table
包,这个更短:
library(data.table)
dt <- data.table(df)
dt[, prop := prop.table(count), by=week]
我不太擅长 dplyr,但我相信还有一个非常简短直接的解决方案。
编辑:这是我在 dplyr/magrittr 中想到的:
library(dplyr)
df3 <- df %>%
group_by(week) %>%
mutate(freq = prop.table(count))
您提供的数据已被使用:
# Loading the required data
df = data.frame(week = as.factor(rep(c(1, 2), times = 5)),
name = as.factor(rep(LETTERS[1:5], times = 2)),
count = rpois(n = 10, lambda = 20))
使用plyr
包函数,计算了标签的百分比和相对位置。
#Loading the required packages
library(plyr)
library(ggplot2)
# Calculating the percentages
df = ddply(df, .(week), transform, percent = round(count/sum(count) * 100))
# Calculating the position for plotting
df = ddply(df, .(week), transform, pos = cumsum(percent) - (0.5 * percent))
利用上面计算的信息,绘图已经完成。
# Basic graph
p10 <- ggplot() + geom_bar(aes(y = percent, x = week, fill = name),
data = df, stat="identity")
# Adding data labels
p10 <- p10 + geom_text(data=df, aes(x = week, y = pos,
label = paste0(percent,"%")), size=4)
p10
这是您一直在寻找的吗?
df = data.frame(week = as.factor(rep(c(1, 2), times = 5)),
name = as.factor(rep(LETTERS[1:5], times = 2)),
count = rpois(n = 10, lambda = 20))
> df
week name count
1 1 A 16
2 2 B 14
3 1 C 23
4 2 D 15
5 1 E 12
6 2 A 15
7 1 B 23
8 2 C 22
9 1 D 22
10 2 E 26
我想计算每个名字每周的计数份额。 起初我打算使用以下方法:
transform(df, week1_share = ifelse(week == "1", round((df$count / sum(df$count) * 100),2), NA))
transform(df, week2_share = ifelse(week == "2", round((df$count / sum(df$count) * 100),2), NA))
但是然后让每一列合并,最终将其作为标签放在条形图上,似乎效率太低了。一定有某种我还不知道的快速解决方案。
基本上我想做的是如下,但添加可能已按上述方法计算的份额百分比以在每个框中匹配。
ggplot(df, aes(reorder(week, -count),count, color = "white", group = name, fill = name))+
geom_bar(position = "stack", stat = "identity") +
scale_y_continuous(labels=comma)+
ggthemes::scale_color_tableau()
我不知道为什么重新排序功能经常在我身上失败。如果您有任何关于 desc 排序的技巧,请分享。
基于 R 的解决方案,使用 split
、unsplit
和 prop.table
将是:
df2 <- unsplit(lapply(split(df, df$week),
function(x){
x$prop <- prop.table(x$count)
x}
), df$week)
简而言之split
returns data.frames
根据第二个参数拆分的列表,unsplit 将拆分产生的列表组合在一起。
使用 data.table
包,这个更短:
library(data.table)
dt <- data.table(df)
dt[, prop := prop.table(count), by=week]
我不太擅长 dplyr,但我相信还有一个非常简短直接的解决方案。
编辑:这是我在 dplyr/magrittr 中想到的:
library(dplyr)
df3 <- df %>%
group_by(week) %>%
mutate(freq = prop.table(count))
您提供的数据已被使用:
# Loading the required data
df = data.frame(week = as.factor(rep(c(1, 2), times = 5)),
name = as.factor(rep(LETTERS[1:5], times = 2)),
count = rpois(n = 10, lambda = 20))
使用plyr
包函数,计算了标签的百分比和相对位置。
#Loading the required packages
library(plyr)
library(ggplot2)
# Calculating the percentages
df = ddply(df, .(week), transform, percent = round(count/sum(count) * 100))
# Calculating the position for plotting
df = ddply(df, .(week), transform, pos = cumsum(percent) - (0.5 * percent))
利用上面计算的信息,绘图已经完成。
# Basic graph
p10 <- ggplot() + geom_bar(aes(y = percent, x = week, fill = name),
data = df, stat="identity")
# Adding data labels
p10 <- p10 + geom_text(data=df, aes(x = week, y = pos,
label = paste0(percent,"%")), size=4)
p10
这是您一直在寻找的吗?