Erreur en utilisant `loess.smooth` mais pas` `loess` ou lowess`
Question
Je dois lisser des données simulées, mais parfois rencontrent des problèmes dans les ordonnées simulées à lissées sont la plupart du temps la même valeur. Voici un petit exemple reproductible du cas le plus simple.
> 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)
et leur analogue à Matlab produisent les résultats attendus sans erreur sur cet exemple. J'utilise loess.smooth
ici parce que je dois les estimations évaluées à un certain nombre de points. Selon la documentation, je crois loess.smooth
et loess
utilisent les mêmes fonctions d'estimation, mais le premier est une « fonction auxiliaire » pour gérer les points d'évaluation. L'erreur semble provenir d'une fonction 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
appelle aussi simpleLoess
, mais avec ce qui semble être des arguments différents. Bien sûr, si vous variez suffisamment des valeurs y être non nul, exécute loess.smooth
sans erreur, mais je dois le programme à exécuter en même le cas le plus extrême de.
Il faut espérer que quelqu'un peut me aider avec l'un et / ou tous les éléments suivants:
- Comprendre pourquoi ne
loess.smooth
, et non les autres fonctions, produit cette erreur et trouver une solution à ce problème. - Trouver un travail autour de l'utilisation
loess
mais encore évaluer l'estimation à un certain nombre de points qui peuvent différer du vecteur x. Par exemple, je pourrais vouloir utiliser uniquementx <- seq(0,50,10)
dans le lissage, mais d'évaluer l'estimation àx <- 0:50
. Pour autant que je sache, à l'aidepredict
avec une nouvelle trame de données ne sera pas gérer correctement cette situation, mais s'il vous plaît laissez-moi savoir si je manque quelque chose. - gérer l'erreur d'une manière qui ne cesse pas le programme de passer à la prochaine série de données simulées.
Merci d'avance pour toute aide sur ce problème.
La solution
Pour la partie 1: Cela a pris un peu de suivi vers le bas, mais si vous le faites:
loess.smooth(x, y, family = "guassian")
le modèle conviendra. Cela se produit en raison des différents paramètres par défaut de loess.smooth
et loess
; l'ancien a family = c("symmetric", "gaussian")
alors que ce dernier a renversé il. Si vous chaluter par le code pour loess
et loess.smooth
, vous verrez que lorsque family = "gaussian"
de iterations
est réglé sur 1
. Sinon, il prend la valeur loess.control()$iterations
. Si vous faites des itérations dans simpleLoess
, l'appel de fonction suivante retourne un vecteur de 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
Ce qui provoque l'appel suivant la fonction de jeter l'erreur que vous avez vu:
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))
Tout cela se rapporte à montage robuste dans loess (méthode). Si vous ne voulez pas / besoin d'un ajustement robuste, l'utilisation family = "gaussian"
dans votre appel loess.smooth
.
En outre, notez que les valeurs par défaut loess.smooth
diffèrent de celles de loess
, par exemple pour 'span'
et 'degree'
. Vérifiez donc soigneusement quels modèles vous voulez adapter et ajuster les paramètres par défaut de la fonction correspondante.
Pour la partie 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)))
Ce qui donne:
> pred
1 2 3 4
NA 0 0 NA
> pred2
1 2 3 4
0 0 0 0
La valeur par défaut ne sera pas si ce extrapolate est ce que vous vouliez dire. Je ne vois pas quel est le problème avec l'utilisation predict
est ici du tout, en fait.
Pour la partie 3:
Regardez ?try
et ?tryCatch
que vous pouvez envelopper autour de la fonction d'ajustement de loess (par exemple de la loess.smooth
), ce qui permettra de continuer les calculs si une erreur est rencontrée loess.smooth
.
Vous devrez gérer la sortie de try
ou tryCatch
en incluant quelque chose comme (si vous faites cela dans une boucle:
mod <- try(loess.smooth(x, y))
if(inherits(mod, "try-error"))
next
## if here, model work, do something with `mod`
Je probablement combiner try
ou tryCatch
avec raccord via loess
et en utilisant predict
pour un tel problème.
Autres conseils
Ceci est la première fois que je rencontrais ces fonctions, donc je ne peux pas vous aider beaucoup, mais pas peut-il avoir quelque chose à voir avec avoir une variance de 0 dans les valeurs y? Maintenant, vous essayez d'estimer une ligne lisse à partir des données déjà est lisse comme qu'il obtient, et ce FONCTIONNE:
x <- 0:50
y <- c(rep(0,25),rep(1,26))
loess.smooth(x,y)