【问题标题】:How can one add a cumulative trend line based on weight to a histogram in R?如何将基于权重的累积趋势线添加到 R 中的直方图?
【发布时间】:2022-08-18 00:00:47
【问题描述】:

在下面的直方图中添加累积趋势线时遇到了一些严重问题。与我能找到的所有示例的主要区别在于 x 轴应该是距离箱,但 y 轴是每箱 tonne.km 的总和.我正在为此使用重量。累积密度曲线应包括重量 = tonne.km。

为此随机生成的一些数据。

distance<-rnorm(1000000, mean = 1000, sd = 500)
tonne.km<-rnorm(1000000, mean = 25000, sd = 500)
dist.tk.test <- structure(tibble(distance, tonne.km))

我的代码:

dist.tk.test %>% 
  ggplot() +
  geom_histogram(aes(x = distance, y=..density.., weight = tonne.km), bins = 50) +
  stat_bin(aes(x = distance, y=cumsum(..density..)),geom=\"line\",color=\"red\") + 
  scale_x_continuous(label = comma,
                     breaks = extended_breaks(10)) +
  scale_y_continuous(labels=function(x)x*1,
                     sec.axis = sec_axis(~ ., labels = scales::percent, name = \"Cumulative Share (%)\"))

这是视觉结果:

我希望这条线遵循第二个 y 轴,而第一个 y 轴具有每个箱的 tonne.km 总和而不是电流密度。

使用 weight=tonne.km 这可能吗?还是我需要使用完全不同的图表?

提前致谢!

  • 你想缩放直方图和线条吗?
  • 嗨昆腾!当然是。第 1 个 y 轴上的 tonne.km,第 2 个 y 轴上的份额百分比。谢谢!

标签: r histogram


【解决方案1】:

geom_histogram 没有 weight 审美所以我不明白你想如何处理 tonne.km。但是如果你想将CDF叠加到直方图上,这里有一个方法。

首先要认识到,经验直方图密度和 ECDF 等密度在不同的尺度上是很多倍的,特别是在分布是连续的且样本很大的情况下。然后,主要技巧是通过最大密度 y 值缩放 ECDF。

library(ggplot2)
library(scales)

distance <- rnorm(1000000, mean = 1000, sd = 500)
tonne.km <- rnorm(1000000, mean = 25000, sd = 500)
dist.tk.test <- data.frame(distance, tonne.km)

bins <- 50L
x_breaks <- 10L

max_y <- max(density(dist.tk.test$distance)$y)

ggplot(dist.tk.test) +
  geom_histogram(
    aes(x = distance, y = ..density..), bins = bins
  ) +
  geom_line(
    aes(
      x = sort(distance),
      y = max_y * seq_along(distance)/length(distance)
    ),
    color = "red"
  ) +
  scale_x_continuous(label = comma,
                     breaks = extended_breaks(x_breaks)) +
  scale_y_continuous(
    name = "Density",
    sec.axis = sec_axis(~ .x / max_y , 
                        labels = scales::percent, 
                        name = "Cumulative Share (%)")
  )

reprex package (v2.0.1) 于 2022 年 8 月 17 日创建


编辑

在下面的评论之后,这是另一个解决方案。
首先计算distance 的总tonne.km
为了做到这一点,必须对距离进行装箱。我使用findInterval 将它们分箱,然后将每个箱的tonne.km(变量breaks)与aggregate 相加。这是图中使用的 data.frame。

library(ggplot2)
library(scales)

set.seed(2022)
distance <- rnorm(1000000, mean = 1000, sd = 500)
tonne.km <- rnorm(1000000, mean = 25000, sd = 500)
dist.tk.test <- data.frame(distance, tonne.km)

breaks <- range(dist.tk.test$distance)
breaks <- round(breaks/100)*100
breaks <- seq(breaks[1], breaks[2], by = 50)
bins <- findInterval(dist.tk.test$distance, breaks)
breaks <- breaks[bins]

new_df <- aggregate(tonne.km ~ breaks, dist.tk.test, sum, na.rm = TRUE)
y_max <- max(new_df$tonne.km, na.rm = TRUE)

x_axis_breaks <- 10L

ggplot(new_df, aes(breaks, tonne.km)) +
  geom_col(position = position_dodge(), width = 100) +
  geom_line(
    aes(
      y = y_max * cumsum(tonne.km)/sum(tonne.km)
    ),
    color = "red"
  ) +
  scale_x_continuous(
    name = "Distance",
    label = comma,
    breaks = extended_breaks(x_axis_breaks)) +
  scale_y_continuous(
    name = "Tonne/Km",
    sec.axis = sec_axis(~ .x/y_max, 
                        labels = scales::percent, 
                        name = "Cumulative Share (%)")
  )
#> Warning: position_dodge requires non-overlapping x intervals

reprex package (v2.0.1) 于 2022 年 8 月 17 日创建

【讨论】:

  • 嗨,瑞,谢谢!但是,问题是您上面的图表没有考虑到每箱 tonne.km 的总和。我基本上想在 x 轴上有一个图形距离序列,例如0-50 公里,50-100 公里。然后,在第一个 y 轴上,所有行程的总和 tonne.km 落入该特定箱,例如 0-50 公里。这可能是 100 千吨公里的数量。我以为我可以用 ggplot 中的 weight = tonne.km 来做到这一点,但我想不是吗?
  • @DavidFærgeman 完成,请参阅编辑。
猜你喜欢
  • 2022-01-18
  • 2019-06-15
  • 2012-12-07
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多