我需要平滑一些模拟数据,但是当要平滑的模拟坐标大多为相同值时,有时会遇到问题。这是最简单情况的一个可重现的小示例。
> 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
可以正常运行,但是即使在最极端的情况下,我也需要程序运行。希望有人可以帮助我完成以下一项和/或全部:
了解为什么只有
loess.smooth
而不是其他函数会产生此错误,并找到解决该问题的方法。使用
loess
找到一种解决方法,但仍要在可能与向量x不同的指定数量的点上评估估计值。例如,我可能只想在平滑中使用x <- seq(0,50,10)
,但要在x <- 0:50
处评估估算值。据我所知,将predict
与新的数据帧一起使用将无法正确处理这种情况,但是如果我在此处缺少任何内容,请告诉我。以不会阻止程序移至下一个模拟数据集的方式处理错误。
在此先感谢您提供任何帮助。
最佳答案
对于第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
来解决此类问题。关于r - 使用`loess.smooth`而不是`loess`或`lowess`时出错,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4645682/