【问题标题】:geom_smooth() with median instead of meangeom_smooth() 中位数而不是平均值
【发布时间】:2021-03-16 17:17:36
【问题描述】:

我正在用 ggplot 构建一个情节。我有数据,其中 y 大部分独立于 X,但我在 X 的低值处随机有一些 Y 的极值。像这样:

set.seed(1)
X <- rnorm(500, mean=5)
y <- rnorm(500)
y[X < 3] <- sample(c(0, 1000), size=length(y[X < 3]),prob=c(0.9, 0.1),  
    replace=TRUE)

我想指出 MEDIAN y 值在 X 值上仍然是恒定的。我可以看到这里基本上是这样的:

mean(y[X < 3])
median(y[X < 3])

如果我绘制 geom_smooth() 图,它确实意味着,并且受异常值的影响很大:

ggplot(data=NULL, aes(x=X, y=y)) + geom_smooth()

我有一些潜在的修复方法。例如,我可以首先使用 group_by/summarize 来制作一个分箱中位数的数据集,然后绘制它。我宁愿不这样做,因为在我的真实数据中,我有很多分面和分组变量,而且要跟踪很多(非理想)。很多情节肯定看起来更好,但日志在我的应用程序中没有很好的解释(中位数确实有很好的解释)

ggplot(data=NULL, aes(x=X, y=y)) + geom_smooth() + 
  scale_y_log10()

最后,我知道 geom_quantile 但我认为我用错了。有没有办法添加错误栏?另外 - 这个 geom_quantile 图看起来太平滑了,我不明白为什么它会向下倾斜。是不是我用错了?

ggplot(data=NULL, aes(x=X, y=y)) + 
  geom_quantile(quantiles=c(0.5))

我意识到这个问题可能有很多解决方法,但如果可能的话,我很想使用 geom_smooth 并提供一个告诉它使用中位数的参数。我希望 geom_smooth 与一致性进行并排比较。我想将均值和中值 geom_smooths 并排显示“嘿,看,Y 和 X 之间的超强模式是由一些大的异常值驱动的,如果我们只看中值,模式就会消失”。

谢谢!!

【问题讨论】:

  • 在引擎盖下,geom_smooth 适合模型。根据数据的大小,使用loessgam,它们都符合平均值。当您使用geom_quantile 时,它使用来自quantreg 包的分位数回归,它适合分位数的线性 近似
  • 你可以在?geom_smooth帮助页面看到内置的平滑方法选项。它们中没有一个(据我所知)被设计为对异常值具有鲁棒性。使用method.args() 调整?loess?mgcv::gam 平滑器可能会有一些运气,但您最好在 stats.stackexchange 上询问方法问题,以获取有关如何获得中值的平滑估计的建议。跨度>

标签: r ggplot2 tidyverse


【解决方案1】:

您可以创建自己的方法以在geom_smooth 中使用。只要您有一个函数可以生成一个对象,predict 泛型可以在该对象上使用名为 x 的列获取数据框并转换为 y 的适当值。

作为示例,让我们创建一个沿运行中位数进行插值的简单模型。我们将它包装在它自己的类中,并赋予它自己的predict 方法:

rolling_median <- function(formula, data, n_roll = 11, ...) {
  x <- data$x[order(data$x)]
  y <- data$y[order(data$x)]
  y <- zoo::rollmedian(y, n_roll, na.pad = TRUE)
  structure(list(x = x, y = y, f = approxfun(x, y)), class = "rollmed")
}

predict.rollmed <- function(mod, newdata, ...) {
  setNames(mod$f(newdata$x), newdata$x)
}

现在我们可以在geom_smooth中使用我们的方法了:

ggplot(data = NULL, aes(x = X, y = y)) + 
  geom_smooth(formula = y ~ x, method = "rolling_median", se = FALSE) 

当然,这看起来不是很“平坦”,但比标准geom_smooth() 的黄土法计算的线方式更平坦:

ggplot(data = NULL, aes(x = X, y = y)) + 
  geom_smooth(formula = y ~ x, color = "red", se = FALSE) +
  geom_smooth(formula = y ~ x, method = "rolling_median", se = FALSE)

现在,我知道这与“回归中位数”不是一回事,所以您可能希望探索不同的方法,但如果您想获得geom_smooth 来绘制它们,您可以这样做关于它。请注意,如果您想要标准错误,则需要让您的 predict 函数返回一个包含名为 fitse.fit 的成员的列表

【讨论】:

  • 很好的演示和解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-07
  • 2020-09-20
  • 2019-01-08
  • 2016-08-01
  • 2018-08-15
  • 1970-01-01
相关资源
最近更新 更多