【问题标题】:Histogram normalization in ggplot2ggplot2中的直方图归一化
【发布时间】:2018-06-04 15:42:26
【问题描述】:

给一个数据框

x <- runif(1000, 0, 10)
y <- c(rep("success", 500), rep("failure", 500))
z <- data.frame(x, y)

是否可以生成类似的直方图

ggplot(z, aes(x, fill = y)) + geom_histogram()

..count.. 归一化为

尝试 = 成功 + 失败

在每个 bin 中使用 ggplot?非常感谢您的帮助。

编辑: 非常感谢大家的回复!!抱歉,我认为我过于简化了我的问题。与我正在使用的数据更接近的数据框是

df <- data.frame(
v1 = runif(128000, 0, 10),
v2 = factor(rep(rep(1:5, c(1,10,8,4,2)), 5120)),
v3 = factor(rep(rep(1:12, c(2,4,4,6,6,6,6,6,6,6,6,6)), 2000)),
v4 = c(rep("success", 64000), rep("failure", 64000)))

只是数据分布不均匀。为了找到 v1-v4 之间的某些模式,我在视觉上探索这些数据,例如由

ggplot(df, aes(v1, fill = v2)) +
geom_histogram(binwidth = 0.2, position = "stack") +
facet_wrap("v3")

ggplot(df %>% filter(v4 == "success"), aes(v1, fill = v2)) +
geom_histogram(binwidth = 0.2, position = "stack") +
facet_wrap("v3")

根据我目前看到的情况,我现在想更进一步,将最后一个图中的 ..count.. (即成功或失败)标准化为每个图中的总尝试次数bin,即尝试=(成功+失败),以获得某种频率图。例如在 v3 facet x, v2 group y, v1 bin z 我希望看到 0.25(来自 100 次成功/400 次尝试)而不是 100 次成功。

编辑 2: 我想到的情节是这样的:

df <- df %>% mutate(v1_bins = cut(v1, breaks = 5))

df_successes <- df %>% group_by(v1_bins, v2, v3, v4) %>% 
filter(v4 == "success") %>% summarise(successes = n()) %>% 
ungroup() %>% select(-v4)

df_attempts <- df %>% group_by(v1_bins, v2, v3) %>% 
summarise(attempts = n()) %>% ungroup()

df_freq <- left_join(df_attempts, df_successes, by = c("v1_bins", "v2", "v3")) %>% 
mutate(success_freq = successes / attempts)

哪些地块

ggplot(df_freq, aes(x = v1_bins, y = success_freq, group = v2)) +
geom_col(aes(fill = v2), position = "identity", alpha = "0.5") +
facet_wrap("v3")

ggplot(df_freq, aes(x = v1_bins, y = success_freq, group = v2)) +
geom_line(aes(colour = v2)) +
facet_wrap("v3")

【问题讨论】:

  • 你能解释一下你的预期输出吗? “标准化” 是什么意思?据我所知,你的情节是堆叠的,所以它已经在每个 bin 中显示success + failure
  • 是的,没错。在现实生活中的数据集中,我使用其他因素进行堆叠和分面,因此我想绘制按这些因素分组的“成功/尝试”或“失败/尝试”。对不起,不准确;这更有意义吗?
  • 您的意思是为每个组创建一个单独的成功/失败直方图方面吗?在这种情况下,我建议您在示例数据中添加一个group 列,以更好地反映您的真实数据集
  • 我已经对我发布的问题添加了一个编辑,因为我认为我过度简化了它。希望有人还在我身边。
  • 我不明白您还需要什么 - 现有答案已经为您指明了如何处理新数据。只需将geom_histogram(position = "stack") 替换为geom_bar(position = "fill")

标签: r ggplot2 histogram


【解决方案1】:

我认为您希望在直方图的每个 bin 中获得成功和失败的比例。一种方法是在数据上创建切点并使用position = "fill" 制作条形图

z %>% 
  mutate(bins = cut(x, breaks = 30)) %>% 
  ggplot(aes(bins, fill = y)) +
  geom_bar(position = "fill") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = .5))

编辑: 根据您的编辑,您似乎正在尝试获取 binned_v1v2v3 的每个组合的成功比例。从您的数据开始,下图显示了这些。它很忙。我将垃圾箱减少到 10 个,因为 30 个实在太多了。

df <- data.frame(
  v1 = runif(128000, 0, 10),
  v2 = factor(rep(rep(1:5, c(1,10,8,4,2)), 5120)),
  v3 = factor(rep(rep(1:12, c(2,4,4,6,6,6,6,6,6,6,6,6)), 2000)),
  v4 = c(rep("success", 64000), rep("failure", 64000)))

df %>% 
  mutate(bins = cut(v1, breaks = 10)) %>% 
  group_by(bins, v2, v3) %>% 
  summarise(success_prop = mean(v4 == "success")) %>% 
  ggplot(aes(bins, success_prop, fill = v2)) +
  geom_col(position = "dodge") + 
  theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = .5)) +
  facet_wrap(~ v3)

【讨论】:

  • 条形图不是直方图。也许这就是 OP 想要的(从问题中很难确定),但它不是所要求的
  • 我对我发布的问题添加了一个编辑,因为我认为我过度简化了它。我真正需要在 y 上绘制的是成功或失败率(即成功/尝试或失败/尝试),条形图仅允许非常简单的情况。
  • 我不确定我是否理解。上图中的条形图显示了 x 变量的每个 bin 的成功/尝试(蓝色)和失败/尝试(红色)。例如,假设在第一个 bin (.0326,.0347] 中有 30 次尝试。假设这 30 次尝试中有 13 次成功。条形的蓝色部分显示此范围内的成功比例x 为 0.43。同一范围内的失败比例为 1 - .43 = .57。
  • 是的,明白了。在这种情况下,这是一个解决方案。但是,如果该图已经由另一个变量 v2 分组,则按成功/失败覆盖另一个分组将阻止读取成功的比例(请参阅上面的编辑 2 了解我想到的图)。跨度>
猜你喜欢
  • 2018-08-02
  • 2014-12-31
  • 2013-06-20
  • 1970-01-01
  • 2015-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多