【问题标题】:How can I "weight" data points before making a density plot in R?在 R 中制作密度图之前,如何“加权”数据点?
【发布时间】:2022-08-05 23:45:50
【问题描述】:

假设我在 tibble activity 中有一些数据,其中有一列 activity$time 记录了某些事件的时间。假设此数据包含两个不同的采样周期,一个从 5:00 到 9:00,一个从 7:00 到 11:00。由于这些时间段重叠,因此 7:00 到 9:00 之间的事件比其他时间段高出 2 倍。如果我要制作这样的密度图:

ggplot(activity) + geom_density(mapping = aes(x = time))

那么与真实反映现实的情况相比,中心将向上倾斜。我如何告诉geom_density() 诸如“将此间隔加权 0.5 倍”之类的东西,或者更好的是,提供任意加权函数?

这是一些演示重叠效果的代码。 runif() 应该会产生均匀分布,但是因为我有两个重叠的部分,所以中间有一个更高的高原:

set.seed(27036459)
activity <- tibble(time = c(runif(10000, 5, 9), runif(10000, 7, 11)))
ggplot(activity) + geom_density(mapping = aes(x = time))

我想要的是一种采用activity 的方法,并利用我对采样间隔的了解,以某种方式调整图表以表示现象的实际分布,与采样偏差无关(在这种情况下,runif() 的均匀性) .

  • 您可以添加一个可重现的示例吗?您可以使用dput() 发布您的数据。

标签: r ggplot2 tibble


【解决方案1】:

我们可以通过从上午 5 点到上午 9 点采集 50 个样本,从上午 7 点到 11 点采集另外 50 个样本,来生成与您自己类似的设置,如下所示:

set.seed(1)

activity <- data.frame(time = as.POSIXct("2022-08-05 05:00:00") +
                         c(runif(50, 0, 14400), c(runif(50, 7200, 21600))))

我们可以看到这会在上午 7 点到 9 点之间产生不需要的峰值:

library(tidyverse)

ggplot(activity) + 
  geom_density(mapping = aes(x = time))

geom_density 中没有 weights 参数,但由于曲线下的面积被标准化为 1,我们是否将 7 和 9 之间的值的权重减半或将这段时间之外的权重加倍并不重要 - 它会给我们同样的结果。然而,后者更容易做到:我们只需创建数据帧的副本,在其中过滤掉 7 和 9 之间的值,然后将其绑定到原始数​​据帧:

library(lubridate)

activity %>%
  filter(hour(time) < 7 | hour(time) > 9) %>%
  bind_rows(activity) %>%
  ggplot() +
  geom_density(mapping = aes(x = time))

reprex package (v2.0.1) 创建于 2022-08-05

【讨论】:

    猜你喜欢
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2020-08-22
    • 2011-08-13
    • 1970-01-01
    • 2015-04-07
    • 1970-01-01
    相关资源
    最近更新 更多