2011-01-10 18 views
7

Ho bisogno di smussare alcuni dati simulati, ma occasionalmente si imbattono in problemi quando le ordinate simulate da livellare sono per lo più lo stesso valore. Ecco un piccolo esempio riproducibile del caso più semplice.Errore nell'uso di `loess.smooth` ma non` loess` o `lowess`

> 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), e il loro analogo in MATLAB produrre i risultati attesi senza errori su questo esempio. Sto usando loess.smooth qui perché ho bisogno delle stime valutate a un determinato numero di punti. Secondo la documentazione, credo che loess.smooth e loess utilizzino le stesse funzioni di stima, ma il primo è una "funzione ausiliaria" per gestire i punti di valutazione. L'errore sembra provenire da una funzione 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 chiama anche simpleLoess, ma con quello che sembra essere diversi argomenti. Ovviamente, se si varia il numero di valori y da zero diversi, loess.smooth viene eseguito senza errori, ma è necessario che il programma venga eseguito anche nel caso più estremo.

Si spera, qualcuno mi può aiutare con uno e/o tutte le seguenti:

  1. Comprendere perché solo loess.smooth, e non le altre funzioni, produce questo errore e trovare una soluzione per questo problema.
  2. Trovare un work-around usando loess ma ancora valutando la stima in un numero specificato di punti che possono differire dal vettore x. Ad esempio, potrei voler usare solo x <- seq(0,50,10) nel livellamento, ma valutare il preventivo a x <- 0:50. Per quanto ne so, l'utilizzo di predict con una nuova cornice dati non gestirà correttamente questa situazione, ma per favore fatemi sapere se mi manca qualcosa lì.
  3. Gestire l'errore in un modo che non impedisca al programma di passare al successivo set di dati simulato.

Grazie in anticipo per qualsiasi aiuto su questo problema.

risposta

7

Da parte 1: questo ha preso un po 'di rintracciare, ma se lo fai :

loess.smooth(x, y, family = "guassian")

il modello si adatta. Ciò si verifica a causa delle diverse impostazioni predefinite di loess.smooth e loess; il primo ha family = c("symmetric", "gaussian") mentre il secondo lo ha invertito. Se si scorre il codice per loess e loess.smooth, questo verrà visualizzato quando family = "gaussian"iterations è impostato su 1. Altrimenti prende il valore loess.control()$iterations.Se lo fai iterazioni nel simpleLoess, la seguente chiamata funzione restituisce un vettore di 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 

che causa la chiamata di funzione successiva di gettare l'errore che hai visto:

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)) 

Tutto questo si riferisce al raccordo robusta in Loess (il metodo). Se non si desidera/necessita di un accoppiamento stabile, utilizzare family = "gaussian" nella chiamata loess.smooth.

Inoltre, notare che i valori predefiniti per loess.smooth differiscono da quelli di loess, ad es. per 'span' e 'degree'. Quindi, controlla attentamente i modelli che desideri adattare e regola i valori predefiniti della funzione pertinente.

Da parte 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))) 

che dà:

> pred 
1 2 3 4 
NA 0 0 NA 
> pred2 
1 2 3 4 
0 0 0 0 

L'impostazione predefinita non estrapolare se questo era quello che volevi dire. Non vedo quale sia il problema con l'uso di predict qui, in effetti.

Da parte 3: Guardate ?try e ?tryCatch che si può avvolgere intorno alla funzione di raccordo loess (loess.smooth dicono), che permetterà di calcoli per continuare, se viene rilevato un errore in loess.smooth.

Sarà necessario gestire l'output di try o tryCatch includendo qualcosa di simile (se si sta facendo questo in un ciclo:

mod <- try(loess.smooth(x, y)) 
if(inherits(mod, "try-error")) 
    next 
## if here, model work, do something with `mod` 

avrei probabilmente combinare try o tryCatch con raccordo via loess e utilizzando predict

+0

eliminato la mia risposta, poiché è lo stesso che hai postato ora. –

+0

@Joris - non è necessario averlo eliminato. Stavo per sviare la risposta! –

+0

Ho aggiunto qualcosa nella parte 1 di t La domanda dell'OP sul perché 'loess.smooth' fallisce con il tipo di problema mostrato. –

0

Questa è la prima volta che ho incontrato queste funzioni, quindi non posso aiutarvi così tanto, ma questo non può avere qualcosa a che fare con una varianza di 0 nei valori y? Ora si cerca di stimare una linea liscia da dati che già è liscio come si arriva, e questo funziona:

x <- 0:50 
y <- c(rep(0,25),rep(1,26)) 
loess.smooth(x,y) 
Problemi correlati