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:

  1. Comprendre pourquoi ne loess.smooth, et non les autres fonctions, produit cette erreur et trouver une solution à ce problème.
  2. 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 uniquement x <- seq(0,50,10) dans le lissage, mais d'évaluer l'estimation à x <- 0:50. Pour autant que je sache, à l'aide predict 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.
  3. 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.

Était-ce utile?

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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top