在R中将ggplot直方图归一化,使第一个高度为1(以显示增长)

4

我想知道是否有一种方法可以归一化具有多个组的直方图的高度,使它们的第一个高度都等于1。例如:

results <- rep(c(1,1,2,2,2,3,1,1,1,3,4,4,2,5,7),3)
category <- rep(c("a","b","c"),15)
data <- data.frame(results,category)
p <- ggplot(data, aes(x=results, fill = category, y = ..count..))
p + geom_histogram(position = "dodge")

生成一个包含3组的普通直方图。

另外,

results <- rep(c(1,1,2,2,2,3,1,1,1,3,4,4,2,5,7),3)
category <- rep(c("a","b","c"),15)
data <- data.frame(results,category)
p <- ggplot(data, aes(x=results, fill = category, y = ..ncount..))
p + geom_histogram(position = "dodge")

给出一个直方图,其中每个组都被归一化为最大高度为1。

我想要一份直方图,其中每个组都被归一化为第一个高度为1(这样我就可以展示增长),但我不知道是否有适当的替代方法来使用“..ncount”或“..count..”,或者是否有人可以帮助我理解“..count..”的结构,从而让我能够从那里弄清楚。谢谢!


3
感谢您的提问,这是一个很好的问题。请提供一个可重现的示例,展示您尝试了什么以及为什么不起作用。欢迎来到SO! - Simon O'Hanlon
2个回答

2

我相信在ggplot中有很多优秀的方法来完成所有事情。然而,我更倾向于在将数据集插入ggplot之前准备所需的数据集。如果我理解你的意思正确,你可以尝试像这样做:

# convert 'results' to factor and set levels to get an equi-spaced 'results' x-axis
df$results <- factor(df$results, levels = 1:7)

# for each category, count frequency of 'results' 
df <- as.data.frame(with(df, table(results, category)))

# normalize: for each category, divide all 'Freq' (heights) with the first 'Freq'
df$freq2 <- with(df, ave(Freq, category, FUN = function(x) x/x[1]))

ggplot(data = df, aes(x = results, y = freq2, fill = category)) +
  geom_bar(stat = "identity", position = "dodge")

enter image description here


非常感谢!这正是我想要做的。不过,我想知道是否有一种方法可以在 ggplot 中自动化此过程,因为对我而言,这似乎应该是一个足够常见的问题,但这确实是一个非常明确和有用的解决方案。谢谢! - conorfrailey
一般来说,如果第一个元素不是最大值的话,你也需要将这一行改为 df$freq2 <- with(df, ave(Freq, category, FUN = function(x) x/max(x))) - colcarroll
@JLLagrange,感谢您的评论。据我理解,这个问题中的值应该相对于第一个高度进行归一化(“每个组都被归一化为第一个高度为1”),而不是最大高度。 - Henrik
抱歉,我又看错了问题。你说得完全正确。 - colcarroll

0

看起来..density..可以实现你想要的功能,但我却找不到相关文档。不过,在你提供的两个例子中,它都能够实现你所需的功能!

results <- rep(c(1,1,2,2,2,3,1,1,1,3,4,4,2,5,7),3)
category <- rep(c("a","b","c"),15)
data <- data.frame(results,category)
p <- ggplot(data, aes(x=results, fill = category, y = ..density..))
p + geom_histogram(position = "dodge")

谢谢您的建议,但它似乎并不完全符合我的要求。当我输入时,我得到的第一个高度是'a'的2,'b'的2和'c'的'1'。 不过我得到的是一个图表,每个类别的总面积都等于1。(它们的基础宽度设置为范围/30,这里是1/5)。 还是非常感谢! - conorfrailey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接