This question may or may not be inspired by my losing an entire 3-hour geocoding run because one of the values returned an error. Cue the pity (down)votes.
Basically there was an error returned inside a function called by sapply
. I had options(error=recover)
on, but despite browsing through every level available to me, I could not find any place where the results of the (thousands of successful) calls to FUN were stored in memory.
Some of the objects I found while browsing around themselves gave errors when I attempted to examine them, claiming the references were no longer valid. Unfortunately I lost the particular error message.
Here's a quick example which, while it does not replicate the reference error (which I suspect is related to disappearing environments and is probably immaterial), does demonstrate that I cannot see a way to save the data that has already been processed.
Is there such a technique?
Note that I have since realized my error and inserted even more robust error handling than existed before via try
, but I am looking for a way to recover the contents ex post rather than ex ante.
Test function
sapply( seq(10), function(x) {
if(x==5) stop("Error!")
return( "important data" )
} )
Interactive exploration
> sapply( seq(10), function(x) {
+ if(x==5) stop("Error!")
+ return( "important data" )
+ } )
Error in FUN(1:10[[5L]], ...) : Error!
Enter a frame number, or 0 to exit
1: sapply(seq(10), function(x) {
if (x == 5)
stop("Error!")
return("important data")
})
2: lapply(X = X, FUN = FUN, ...)
3: FUN(1:10[[5]], ...)
Selection: 3
Called from: FUN(1:10[[5L]], ...)
Browse[1]> ls()
[1] "x"
Browse[1]> x
[1] 5
Browse[1]>
Enter a frame number, or 0 to exit
1: sapply(seq(10), function(x) {
if (x == 5)
stop("Error!")
return("important data")
})
2: lapply(X = X, FUN = FUN, ...)
3: FUN(1:10[[5]], ...)
Selection: 2
Called from: lapply(X = X, FUN = FUN, ...)
Browse[1]> ls()
[1] "FUN" "X"
Browse[1]> X
[1] 1 2 3 4 5 6 7 8 9 10
Browse[1]> FUN
function(x) {
if(x==5) stop("Error!")
return( "important data" )
}
Browse[1]>
Enter a frame number, or 0 to exit
1: sapply(seq(10), function(x) {
if (x == 5)
stop("Error!")
return("important data")
})
2: lapply(X = X, FUN = FUN, ...)
3: FUN(1:10[[5]], ...)
Selection: 1
Called from: sapply(seq(10), function(x) {
if (x == 5)
stop("Error!")
return("important data")
})
Browse[1]> ls()
[1] "FUN" "simplify" "USE.NAMES" "X"
Browse[1]> X
[1] 1 2 3 4 5 6 7 8 9 10
Browse[1]> USE.NAMES
[1] TRUE
Browse[1]> simplify
[1] TRUE
Browse[1]> FUN
function(x) {
if(x==5) stop("Error!")
return( "important data" )
}
Browser[1]> Q
To be clear, what I was hoping to find was the vector:
[1] "important data" "important data" "important data" "important data"
In other words, the results of the internal loop that had been completed to this point.
Edit: Update with C code
Inside .Internal(lapply())
is the following code:
PROTECT(ans = allocVector(VECSXP, n));
...
for(i = 0; i < n; i++) {
...
tmp = eval(R_fcall, rho);
...
SET_VECTOR_ELT(ans, i, tmp);
}
I want to get at ans
when any call to lapply
fails.