acn*_*acn 1 r ggplot2 tidyverse
我正在用 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)
Run Code Online (Sandbox Code Playgroud)
我想指出的是,y 值中位数对于 X 值而言仍然是常数。我可以看到这基本上是正确的:
mean(y[X < 3])
median(y[X < 3])
Run Code Online (Sandbox Code Playgroud)
如果我制作一个 geom_smooth() 图,它确实意味着,并且受异常值的影响很大:
ggplot(data=NULL, aes(x=X, y=y)) + geom_smooth()
Run Code Online (Sandbox Code Playgroud)
我有一些潜在的修复方法。例如,我可以首先使用 group_by/summarize 制作分箱中位数的数据集,然后绘制它。我宁愿不这样做,因为在我的真实数据中,我有很多分面和分组变量,并且需要跟踪很多(非理想)。很多图肯定看起来更好,但日志在我的应用程序中没有很好的解释(中位数确实有很好的解释)
ggplot(data=NULL, aes(x=X, y=y)) + geom_smooth() +
scale_y_log10()
Run Code Online (Sandbox Code Playgroud)
最后,我了解 geom_quantile 但我认为我使用错误。有没有办法添加误差线?另外-这个 geom_quantile 图看起来太平滑了,我不明白为什么它向下倾斜。难道是我用错了?
ggplot(data=NULL, aes(x=X, y=y)) +
geom_quantile(quantiles=c(0.5))
Run Code Online (Sandbox Code Playgroud)
我意识到这个问题可能有很多解决方法,但如果可能的话,我很想使用 geom_smooth 并只提供一个参数告诉它使用中位数。我想要 geom_smooth 来进行并排比较和一致性。我想将平均值和中值 geom_smooths 并排放置以显示“嘿,看,Y 和 X 之间的超强模式是由一些大的异常值驱动的,如果我们只看中值,模式就会消失”。
谢谢!!
您可以创建自己的方法以在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)
}
Run Code Online (Sandbox Code Playgroud)
现在我们可以在以下位置使用我们的方法geom_smooth
:
ggplot(data = NULL, aes(x = X, y = y)) +
geom_smooth(formula = y ~ x, method = "rolling_median", se = FALSE)
Run Code Online (Sandbox Code Playgroud)
当然,现在看起来不是很“平坦”,但它比标准的黄土方法计算的线平坦得多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)
Run Code Online (Sandbox Code Playgroud)
现在,我知道这与“中位数回归”不同,因此您可能希望探索不同的方法,但如果您想geom_smooth
绘制它们,这就是您可以采取的方法。请注意,如果您想要标准错误,则需要让predict
函数返回一个列表,其中包含调用的成员fit
和se.fit