如果我有这样的数据集
set.seed(100)
data <- data.frame("x" = c(1, 1, 1, 2, 2, 2, 3, 4, 4, 4, 5, 5, 5),
"y" = rnorm(13),
"factor" = c("a","b","c","a","b", "c", "c", "a",
"b", "c", "a", "b","c"))
所以它看起来像这样
x y factor
1 1 -0.50219235 a
2 1 0.13153117 b
3 1 -0.07891709 c
4 2 0.88678481 a
5 2 0.11697127 b
6 2 0.31863009 c
7 3 -0.58179068 c
8 4 0.71453271 a
9 4 -0.82525943 b
10 4 -0.35986213 c
11 5 0.08988614 a
12 5 0.09627446 b
13 5 -0.20163395 c
我想用一个单独的更平滑的每个因子(a,b,c)
来绘制library(ggplot2)
ggplot(data = data, aes(x = x, y = y, col = factor)) +
geom_smooth(aes(group = factor))
然而,由于x = 3没有“a”和“b”的值,所以我希望“a”和“b”的平滑器有一个x = 3的中断。什么是最好的策略完成那个?
答案 0 :(得分:2)
我会创建factor
和df
组合的扩展,然后对组合和数据进行类似数据库的连接。例如,首先我使用x
和factor
df <- expand.grid(sapply(data[, c("x", "factor")], unique))
> df
x factor
1 1 a
2 2 a
3 3 a
4 4 a
5 5 a
6 1 b
7 2 b
8 3 b
9 4 b
10 5 b
11 1 c
12 2 c
13 3 c
14 4 c
15 5 c
df
然后我们可以简单地对data
和你的x
执行连接操作,请求我们从左侧返回所有行(df
参数,因此{{ 1}}),并在右侧包含y
的相应值(data
)。如果没有相应的右侧(data
,我们会得到NA
。
newdf <- merge(df, data, all.x = TRUE)
> newdf
x factor y
1 1 a -0.50219235
2 1 b 0.13153117
3 1 c -0.07891709
4 2 a 0.88678481
5 2 b 0.11697127
6 2 c 0.31863009
7 3 a NA
8 3 b NA
9 3 c -0.58179068
10 4 a 0.71453271
11 4 b -0.82525943
12 4 c -0.35986213
13 5 a 0.08988614
14 5 b 0.09627446
15 5 c -0.20163395
现在我们可以手工拟合并预测黄土模型,但这有点单调乏味 - 通过mgcv:gam()
可以获得更简单的选项
loessFun <- function(XX, span = 0.85) {
fit <- loess(y ~ x, data = XX, na.action = na.exclude, span = span)
predict(fit)
}
现在按factor
拆分数据并应用loessFun()
包装
fits <- lapply(split(newdf, newdf$factor), loessFun)
newdf <- transform(newdf, fitted = unsplit(fits, factor))
> head(newdf)
x factor y fitted
1 1 a -0.50219235 -0.50219235
2 1 b 0.13153117 0.13153117
3 1 c -0.07891709 -0.07891709
4 2 a 0.88678481 0.88678481
5 2 b 0.11697127 0.11697127
6 2 c 0.31863009 0.31863009
然后我们可以使用新数据框
进行绘图ggplot(newdf, aes(x = x, y = y, col = factor)) +
geom_line(aes(group = factor))
给出:
由于您提供的样本数据的分辨率非常低,并且因为我使用的这种方法仅在观察到的数据上进行预测,因此它看起来有点时髦,保留了NA
s。 geom_smooth()
实际上是分别针对每个组的x
范围进行预测,因此在用于绘制geom图层的数据中没有丢失x
。
除非您可以在x = 3
的哪个区域内解释我们应该添加休息(NA
),否则这可能是您可以做的最好的。或者,我们可以从模型中预测区域,然后将任何2.5 < x < 3.5
设置回NA
。如果这是您想要的,请添加评论,我将通过一个示例扩展我的答案如果您可以指出我们如何设想差距。