我需要平滑一些模拟数据,但是当要平滑的模拟纵坐标几乎是相同的值时偶尔会遇到问题。这是最简单案例的一个可重复的小例子。
> 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
将无法正确处理这种情况,但如果我遗漏了某些内容,请告诉我。 提前感谢您对此问题的任何帮助。
答案 0 :(得分:8)
第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
中的错误,将允许计算继续。< / p>
您需要通过包含类似的内容来处理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
来解决此类问题。
答案 1 :(得分:0)
这是我第一次遇到这些功能,所以我无法帮助你,但这不能与y值的方差为0有关吗?现在,您尝试从已经尽可能平滑的数据中估计平滑线,这确实有效:
x <- 0:50
y <- c(rep(0,25),rep(1,26))
loess.smooth(x,y)