我需要平滑一些模拟数据,但是当要平滑的模拟坐标大多为相同值时,有时会遇到问题。这是最简单情况的一个可重现的小示例。

> 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.smoothloess使用的是相同的估算函数,但前者是用于处理评估点的“辅助函数”。该错误似乎来自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可以正常运行,但是即使在最极端的情况下,我也需要程序运行。

希望有人可以帮助我完成以下一项和/或全部:


了解为什么只有loess.smooth而不是其他函数会产生此错误,并找到解决该问题的方法。
使用loess找到一种解决方法,但仍要在可能与向量x不同的指定数量的点上评估估计值。例如,我可能只想在平滑中使用x <- seq(0,50,10),但要在x <- 0:50处评估估算值。据我所知,将predict与新的数据帧一起使用将无法正确处理这种情况,但是如果我在此处缺少任何内容,请告诉我。
以不会阻止程序移至下一个模拟数据集的方式处理错误。


在此先感谢您提供任何帮助。

最佳答案

对于第1部分:
这需要一些跟踪,但是如果您这样做:

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

该模型将适合。这是由于loess.smoothloess的默认值不同而引起的;前者具有family = c("symmetric", "gaussian"),而后者则具有反向。如果浏览loessloess.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中的错误,它们将允许计算继续进行。

您将需要通过包含以下内容来处理trytryCatch的输出(如果您在循环中执行此操作:

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


我可能会将trytryCatch与通过loess进行拟合并使用predict来解决此类问题。

关于r - 使用`loess.smooth`而不是`loess`或`lowess`时出错,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4645682/

10-12 17:19