我需要平滑一些模拟数据,但是当要平滑的模拟纵坐标几乎是相同的值时,偶尔会遇到问题.这是最简单案例的一个可重复的小例子.
> 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)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
这会导致下一个函数调用抛出您看到的错误:
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))
Run Code Online (Sandbox Code Playgroud)
这一切都与黄土中的鲁棒拟合(方法)有关.如果您不想/需要健壮,请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)))
Run Code Online (Sandbox Code Playgroud)
这使:
> pred
1 2 3 4
NA 0 0 NA
> pred2
1 2 3 4
0 0 0 0
Run Code Online (Sandbox Code Playgroud)
如果这是你的意思,默认不会推断.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`
Run Code Online (Sandbox Code Playgroud)
我可能会结合try或tryCatch通过适合通过loess和使用predict这样的问题.