如何平滑/平均分布不均的数据?

时间:2018-10-18 09:07:07

标签: r

我有一组来自实验的数据。

由于采集数据的方式,采集点分布非常不均匀。

我需要计算数据集的平均值以及给定x位置附近的平均值。

由于我无法在此处复制数据集,请在下面找到类似数据集的可复制示例。

首先,让我们定义一个均匀分布的数据集:

set.seed(10)

x <- jitter(seq(0, 3, by = 0.3), factor = 1)
y <- sin(x)^2 + rnorm(length(x), sd = 0.1)

my.df <- data.frame(x, y)

ggplot(my.df, aes(x, y)) + geom_point() + geom_smooth(method = "loess") +
  geom_line(data = data.frame(x, y = sin(x)^2), color = "red")

可以看到,黄土平滑功能正确地符合“理论”结果。如果我计算数据集的均值,那么结果将接近理论均值。

现在,让我们添加其他数据:

x1 <- jitter(seq(0.95, 1.05, length.out = 100), factor = 50)
y1 <- sin(x1)^2 + rnorm(length(x1), sd = 0.1)

my.df1 <- rbind(my.df, data.frame(x = x1, y = y1))
ggplot(my.df1, aes(x, y)) + geom_point() + geom_smooth(method = "loess") +
  geom_line(data = data.frame(x, y = sin(x)^2), color = "red")

现在您可以看到黄土平滑度与理论曲线相差甚远。而且,由于我在x = 1位置附近有大量数据,因此全局平均值将离理论曲线更远。

平滑的y值,例如x = 1.5也将很远。

使用Zoo rollmean功能也无法解决问题。实际上,移动平均值是在数据帧中具有接近索引的n个点上计算的,不一定沿x接近。

我想要做的是计算一条趋势线,或者计算沿x而不是点索引平均的移动平均值。

我当时正在考虑对移动的数据子集(例如在[0,0.1],[0.1,0.2]等上,是否有执行该功能的函数?还是我必须使用类似的东西:

mean.values <- c()
for (i in 0:9) {
  print(paste("[", i/10, ", ", (i+1)/10, "]", sep = ""))
  mean.values <- c(mean.values, mean(subset(my.df1, x >= i/10 & x <= (i+1)/10)$y))
} 

编辑:我对数据了解的一件事是,对于给定的x,y的测量值应为“接近”。它们偏离理论曲线的唯一原因是由于采集不确定性。

1 个答案:

答案 0 :(得分:1)

您可以像这样构造权重并调整跨度:

my.df1 <- my.df1[order(my.df1$x),]
d <- diff(my.df1$x)
my.df1$w <- c(max(d), d) + c(d, max(d))/2

ggplot(my.df1, aes(x, y)) + geom_point() + 
  geom_smooth(method = "loess", aes(weight = w), span = 0.95) +
  geom_line(data = data.frame(x, y = sin(x)^2), color = "red")

resulting plot