Ошибка использования `loess.smooth`, но не` loess` или `lowess` - PullRequest
7 голосов
/ 10 января 2011

Мне нужно сгладить некоторые моделируемые данные, но иногда возникают проблемы, когда моделируемые ординаты, которые должны быть сглажены, в основном имеют одинаковое значение.Вот небольшой воспроизводимый пример простейшего случая.

> x <- 0:50
> y <- rep(0,51)
> loess.smooth(x,y)
Error in simpleLoess(y, x, w, span, degree, FALSE, FALSE, normalize = FALSE,  : 
   NA/NaN/Inf in foreign function call (arg 1)

loess(y~x), lowess(x,y) и их аналог в MATLAB дают ожидаемые результаты без ошибок в этом примере.Я использую loess.smooth здесь, потому что мне нужно, чтобы оценки оценивались в определенном количестве баллов.Согласно документации, я считаю, что loess.smooth и loess используют одни и те же функции оценки, но первая является «вспомогательной функцией» для обработки точек оценки.Кажется, ошибка происходит от функции C:

> traceback()
3: .C(R_loess_raw, as.double(pseudovalues), as.double(x), as.double(weights), 
   as.double(weights), as.integer(D), as.integer(N), as.double(span), 
   as.integer(degree), as.integer(nonparametric), as.integer(order.drop.sqr), 
   as.integer(sum.drop.sqr), as.double(span * cell), as.character(surf.stat), 
   temp = double(N), parameter = integer(7), a = integer(max.kd), 
   xi = double(max.kd), vert = double(2 * D), vval = double((D + 
       1) * max.kd), diagonal = double(N), trL = double(1), 
   delta1 = double(1), delta2 = double(1), as.integer(0L))
2: simpleLoess(y, x, w, span, degree, FALSE, FALSE, normalize = FALSE, 
   "none", "interpolate", control$cell, iterations, control$trace.hat)
1: loess.smooth(x, y)

loess также вызывает simpleLoess, но с другими аргументами.Конечно, если вы меняете достаточно много значений y, чтобы быть ненулевым, loess.smooth запускается без ошибок, но мне нужно, чтобы программа работала даже в самом крайнем случае.

Надеюсь, кто-нибудь может помочь мне с одним и / или всеми из следующих действий:

  1. Понять, почему только loess.smooth, а не другие функции, выдает эту ошибку и найтиРешение этой проблемы.
  2. Найдите обходной путь, используя loess, но все еще оценивая оценку в указанном количестве точек, которые могут отличаться от вектора x.Например, я мог бы хотеть использовать только x <- seq(0,50,10) в сглаживании, но оценивать оценку в x <- 0:50.Насколько я знаю, использование predict с новым фреймом данных не поможет должным образом справиться с этой ситуацией, но, пожалуйста, дайте мне знать, если я что-то там упустил.
  3. Обработайте ошибку так, чтобы программа не остановила переход к следующему смоделированному набору данных.

Заранее благодарим за любую помощь по этой проблеме.

Ответы [ 2 ]

8 голосов
/ 10 января 2011

Для части 1: Это заняло некоторое отслеживание, но если вы сделаете:

loess.smooth(x, y, family = "guassian")

модель подойдет.Это возникает из-за различных значений по умолчанию loess.smooth и loess;первый имеет family = c("symmetric", "gaussian"), в то время как последний имеет обратное.Если вы перебираете код для loess и loess.smooth, вы увидите, что когда family = "gaussian" iterations установлено на 1.В противном случае он принимает значение loess.control()$iterations.Если вы выполняете итерации в simpleLoess, следующий вызов функции возвращает вектор NaN:

pseudovalues <- .Fortran(R_lowesp, as.integer(N), as.double(y), 
            as.double(z$fitted.values), as.double(weights), as.double(robust), 
            integer(N), pseudovalues = double(N))$pseudovalues

, что приводит к тому, что следующий вызов функции выдаст ошибку, которую вы видели:

zz <- .C(R_loess_raw, as.double(pseudovalues), as.double(x), 
            as.double(weights), as.double(weights), as.integer(D), 
            as.integer(N), as.double(span), as.integer(degree), 
            as.integer(nonparametric), as.integer(order.drop.sqr), 
            as.integer(sum.drop.sqr), as.double(span * cell), 
            as.character(surf.stat), temp = double(N), parameter = integer(7), 
            a = integer(max.kd), xi = double(max.kd), vert = double(2 * 
                D), vval = double((D + 1) * max.kd), diagonal = double(N), 
            trL = double(1), delta1 = double(1), delta2 = double(1), 
            as.integer(0L))

Все это относится к надежной подгонке в Лёссе (метод).Если вы не хотите / нуждаетесь в надежной подгонке, используйте family = "gaussian" в своем вызове loess.smooth.

Также обратите внимание, что значения по умолчанию для loess.smooth отличаются от значений по умолчанию loess, например для 'span' и 'degree'.Поэтому внимательно проверьте, какие модели вы хотите установить, и отрегулируйте значения по умолчанию для соответствующей функции.

Для части 2:

DF <- data.frame(x = 0:50, y = rep(0,51))
mod <- loess(y ~ x, data = DF)
pred <- predict(mod, newdata = data.frame(x = c(-1, 10, 15, 55)))
mod2 <- loess(y ~ x, data = DF, control = loess.control(surface = "direct"))
pred2 <- predict(mod2, newdata = data.frame(x = c(-1, 10, 15, 55)))

Что дает:

> pred
 1  2  3  4 
NA  0  0 NA 
> pred2
1 2 3 4 
0 0 0 0

Значение по умолчанию не будет экстраполироваться, если вы это имели в виду.Я вообще не вижу, в чем здесь проблема с использованием predict.

Для части 3: Посмотрите на ?try и ?tryCatch, которые можно обернутьокруглить функцию подбора лесса (скажем, loess.smooth), которая позволит продолжить вычисления, если возникнет ошибка в loess.smooth.

Вам потребуется обработать вывод try или tryCatch с помощьювключая что-то вроде (если вы делаете это в цикле:

mod <- try(loess.smooth(x, y))
if(inherits(mod, "try-error"))
    next
## if here, model work, do something with `mod`

Я бы, вероятно, объединил try или tryCatch с подгонкой через loess и использованием predict для такой проблемы.

0 голосов
/ 10 января 2011

Впервые я столкнулся с этими функциями, поэтому не могу вам чем-то помочь, но разве это не связано с наличием дисперсии 0 в значениях y?Теперь вы пытаетесь оценить гладкую линию по данным, которые уже настолько гладкие, насколько это возможно, и это работает:

x <- 0:50
y <- c(rep(0,25),rep(1,26))
loess.smooth(x,y)
...