В ggplot ограничивают y, чтобы быть> 0 в ЛЕССЕ

Вот мой код:

#data
sites <- 
  structure(list(site = c(928L, 928L, 928L, 928L, 928L, 928L, 928L,
                          928L, 928L, 928L, 928L, 928L, 928L, 928L,
                          928L, 928L, 928L, 928L, 928L, 928L, 928L,
                          928L, 928L, 928L, 928L, 928L), 
                 date = c(13493L, 13534L, 13566L, 13611L, 13723L,
                          13752L, 13804L, 13837L, 13927L, 14028L,
                          14082L, 14122L, 14150L, 14182L, 14199L,
                          16198L, 16279L, 16607L, 16945L, 17545L,
                          17650L, 17743L, 17868L, 17941L, 18017L, 18092L),
                 y = c(7L, 7L, 17L, 18L, 17L, 17L, 10L, 3L, 17L, 24L, 
                       11L, 5L, 5L, 3L, 5L, 14L, 2L, 9L, 9L, 4L, 7L,
                       6L, 1L, 0L, 5L, 0L)), 
            .Names = c("site", "date", "y"),
            class = "data.frame", row.names = c(NA, -26L))

#convert to date
x<-as.Date(sites$date, origin="1960-01-01") 

#plot smooth, line goes below zero!
qplot(data=sites, x, y, main="Site 349") 
(p <- qplot(data = sites, x, y, xlab = "", ylab = ""))
(p1 <- p + geom_smooth(method = "loess",span=0.5, size = 1.5))

Часть из LOESS строки и доверительные интервалы понижаются нуль, я хотел бы ограничить графику 0 и положительные числа (потому что отрицательный не имеют смысла). enter image description here

Как я могу сделать это?

10
задан zx8754 12 August 2014 в 09:28
поделиться

2 ответа

Я не могу проверить это без некоторых данных примера, но

qplot(data=sites, x, y, main="Site 349")  
(p <- qplot(data = sites, x, y, xlab = "", ylab = "")) 
(p1 <- p + geom_smooth(method = "loess",span=0.5, size = 1.5)) 
p1 + theme_bw() + opts(title = "Site 349") + ylim(0, foo)

(где foo - подходящий верхний предел для вашего графика) может помочь . В отличие от базовой графики, команды xlim () и ylim () в ggplot фактически ограничивают данные, которые используются при построении графика, а не только окно графика. Это также может ограничить geom_smooth () (хотя я не уверен).

Изменить: Прочитав немного больше, вы также можете подумать об отключении модели, которую использует geom_smooth. Опять же, отсутствие возможности видеть ваши данные - проблема. Но, например, если он двоичный - вы можете добавить stat_smooth (method = "glm", family = "binomial") , чтобы получить логит-сглаженную линию. См. ? Stat_smooth для получения дополнительной информации.

4
ответ дан 3 December 2019 в 20:03
поделиться

Я поддерживаю предложение Мэтта Паркера о том, что вам нужно изменить процедуру подгонки. Один из вариантов, который часто работает для данных, имеющих только положительные значения, заключается в том, чтобы выполнить подгонку по логарифмической шкале, а затем экспонентировать, чтобы получить результаты в исходном масштабе. Это гарантирует получение только положительных значений.

Генерация случайных данных, которые имеют некоторые из этих проблем:

 d <- data.frame(x=0:100)
 d$y <- exp(rnorm(nrow(d), mean=-d$x/40, sd=0.8))
 qplot(x,y,data=d) + stat_smooth() 

Теперь мы можем использовать возможности трансформации ggplot, чтобы преобразовать значения y в логарифмическую шкалу, но отобразить результаты на экспоненциальной шкале (которая соответствует исходной):

qplot(x,y,data=d) + stat_smooth() + scale_y_log10()+coord_trans(ytrans="pow10")

Подобные примеры вы можете увидеть на странице помощи coord_trans. Если вам не нравится ось y, вы можете манипулировать разрывами и метками.

EDIT на основе обновления вопроса

Со времени первоначального вопроса произошли некоторые изменения в ggplot2, и первоначальный ответ не имел дела с 0.

Вариант 1

Основная идея решения та же: найдите преобразование, которое отобразит диапазон возможных значений от -Inf до Inf, выполните сглаживание по Лоссу, а затем обратно преобразуйте результат. Лог-преобразование было бы замечательным, если бы не было нулей. Я не думаю, что необходимая функция существует, если 0 включен, но возможный вариант, который часто работает - это преобразование log(1+x). Оно встроено, но нам нужно иметь и обратное преобразование exp(x)-1.

library(scales)
#create exp(x)-1 transformation, the inverse of log(1+p)
expm1_trans <-  function() trans_new("expm1", "expm1", "log1p")

qplot(x, y, data=sites) + stat_smooth(method="loess") +
  scale_y_continuous(trans=log1p_trans()) +
  coord_trans(ytrans=expm1_trans())

Loess fit on log(1+x) transformed data

Вариант 2

Второй вариант расширяет предложение в комментариях к ответу Мэтта Паркера: используйте метод регрессии, который учитывает целочисленный характер результатов. Это означает перераспределенную (на всякий случай) регрессию Пуассона для подсчетов. Хотя вы не можете использовать метод Лоэсса, вы можете использовать сплайн. Вы можете играть со степенями свободы, чтобы контролировать гладкость.

library(splines)
qplot(x, y, data=sites) + stat_smooth(method="glm", family="quasipoisson", 
                                      formula = y ~ ns(x, 3))

Spline fit using overdispersed Poisson regression

Эти два варианта дают довольно похожие результаты, что хорошо.

15
ответ дан 3 December 2019 в 20:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: