Как создать пробелы в Smoother для отсутствующих значений (R, ggplot)

Если у меня есть такой набор данных

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))

Однако, поскольку нет значений для «a» и «b» для x = 3, поэтому я хотел бы, чтобы у сглаживателей для «a» и «b» был перерыв для x = 3. Какова наилучшая стратегия для этого?


person Jon Sjöberg    schedule 30.06.2015    source источник
comment
что вы имеете в виду под перерывом?   -  person Colonel Beauvel    schedule 01.07.2015


Ответы (1)


Я бы создал расширение комбинаций x и 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), и включили соответствующие значения для 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))

который дает:

введите здесь описание изображения

Это выглядит немного странно из-за очень низкого разрешения предоставленных вами выборочных данных и из-за того, что этот метод, который я использовал, предсказывает только наблюдаемые данные, сохраняя NAs. geom_smooth() на самом деле прогнозируется в диапазоне x для каждой группы отдельно, и поэтому в данных, используемых для рисования слоя геометрии, нет пропущенных x.

Если вы не можете объяснить, в какой области x = 3 мы должны добавить разрыв (NA), это может быть лучшее, что вы можете сделать. В качестве альтернативы мы могли бы предсказать регион по моделям, а затем установить значение 2.5 < x < 3.5 обратно в значение NA. Добавьте комментарий, если это то, что вы хотели, и я дополню свой ответ примером того, как это сделать, если вы можете указать, как мы должны предусмотреть пробелы.

person Gavin Simpson    schedule 30.06.2015