Ottenere lo stato delle variabili dopo che si è verificato un errore in R
Domanda
Diciamo che ho appena chiamato una funzione, f
, e si è verificato un errore da qualche parte nella funzione. Voglio solo essere in grado di verificare i valori di diverse variabili proprio prima che si verificasse l'errore.
Supponi che il mio istinto mi dica che è un piccolo bug, quindi sono troppo pigro per usare debug (f)
e troppo pigro per inserire browser ()
nella parte della funzione in cui penso che le cose stiano andando male. E sono troppo pigro per iniziare a inserire le istruzioni print ()
.
Ecco un esempio:
x <- 1:5
y <- x + rnorm(length(x),0,1)
f <- function(x,y) {
y <- c(y,1)
lm(y~x)
}
Chiamando f (x, y)
viene visualizzato il seguente errore:
Error in model.frame.default(formula = y ~ x, drop.unused.levels = TRUE) :
variable lengths differ (found for 'x')
In questo esempio, voglio prendere lo stato dell'ambiente appena prima di chiamare lm ()
; in questo modo posso chiamare x
e y
e vedere che le loro lunghezze sono diverse. (Questo esempio potrebbe essere troppo semplice, ma spero che l'idea venga trasmessa.)
Soluzione
Come sottolineato qui , c'è un facile modo per farlo, e penso che questo trucco abbia il potenziale per cambiare la vita in meglio.
Per prima cosa, chiama questo:
options(error=recover)
Ora quando chiamiamo f (x, y)
avremo un'opzione per scegliere un ambiente da recuperare. Qui seleziono l'opzione 1, che apre un debugger e mi permette di giocare con le variabili appena prima di chiamare lm ()
.
> f(x,y)
Error in model.frame.default(formula = y ~ x, drop.unused.levels = TRUE) :
variable lengths differ (found for 'x')
Enter a frame number, or 0 to exit
1: f(x, y)
2: lm(y ~ x)
3: eval(mf, parent.frame())
4: eval(expr, envir, enclos)
5: model.frame(formula = y ~ x, drop.unused.levels = TRUE)
6: model.frame.default(formula = y ~ x, drop.unused.levels = TRUE)
Selection: 1
Called from: eval(expr, envir, enclos)
Browse[1]> x
[1] 1 2 3 4 5
Browse[1]> y
[1] 1.6591197 0.5939368 4.3371049 4.4754027 5.9862130 1.0000000
Altri suggerimenti
Puoi anche semplicemente usare la funzione debug ():
> debug(f)
> f(x,y)
debugging in: f(x, y)
debug: {
y <- c(y, 1)
lm(y ~ x)
}
Browse[1]>
debug: y <- c(y, 1)
Browse[1]> x
[1] 1 2 3 4 5
Browse[1]> y
[1] 2.146553 2.610003 2.869081 2.758753 4.433881
Opzioni (errore = recuperare)
Probabilmente risponde meglio alla domanda. Tuttavia, volevo menzionare un altro utile strumento di debug, traceback ()
. Chiamarlo subito dopo che si è verificato un errore è spesso sufficiente per individuare il bug.