如何为“缺失”值创造更平滑的差距(R,ggplot)

时间:2015-06-30 21:00:33

标签: r ggplot2 smooth

如果我有这样的数据集

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的中断。什么是最好的策略完成那个?

1 个答案:

答案 0 :(得分:2)

我会创建factordf组合的扩展,然后对组合和数据进行类似数据库的连接。例如,首先我使用xfactor

的唯一值组合形成新数据框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))

给出:

enter image description here

由于您提供的样本数据的分辨率非常低,并且因为我使用的这种方法仅在观察到的数据上进行预测,因此它看起来有点时髦,保留了NA s。 geom_smooth()实际上是分别针对每个组的x范围进行预测,因此在用于绘制geom图层的数据中没有丢失x

除非您可以在x = 3的哪个区域内解释我们应该添加休息(NA),否则这可能是您可以做的最好的。或者,我们可以从模型中预测区域,然后将任何2.5 < x < 3.5设置回NA。如果这是您想要的,请添加评论,我将通过一个示例扩展我的答案如果您可以指出我们如何设想差距。