So I am using a function in R that uses compiled fortran code. While using this function, lsoda, in package deSolve. I get messages printed to the screen like
DLSODA- At current T (=R1), MXSTEP (=I1) steps
taken on this call before reaching TOUT
In above message, I =
[1] 5000
In above message, R =
[1] 21.31629
The problem is that the above is not a "warning" or an "error"; the is.null(warnings()) evaluates to TRUE after I see this message. If it were a warning I could just write x = is.null(warnings()) and that would do the trick. I could use tryCatch for errors, but what about messages that are neither errors or warnings?
The reason I ask, is that this function is called in a while loop, inside a for loop. I want the while loop to break if this message gets printed, and then for the outer for loop to move onto the next iteration. Normally you'd use tryCatch to do something like this but because there is no error, I have no idea how to do this
You can redirect the output and then check whether lsoda printed something:
out <- capture.output(lsoda(...))
if(length(grep("In above message", out))!=0) {
# error
}
We basically check whether any of the lines printed by lsoda contains the string In above message. If you need to use the result from lsoda, you can also run like this:
out <- capture.output(result <- lsoda(...))
As suggested, you can also use grepl:
if(any(grepl("In above message", out))) {
# error
}
Related
I am using the function FixedPoint() from the package FixedPoint for some computations in R. Even if a fixed point of some function cannot be found, FixedPoint() still returns output (indicating the error) and, in addition, returns an error message. I want to suppress any such additional error messages from being printed. Neither try(), nor suppressWarnings(), nor suppressMessages() seem to work. Please find an example below that produces such an additional error message.
library(FixedPoint)
ell=0.95
delta=0.1
r=0.1
lambda=1
tH=1
tL=0.5
etaL=1
etaH=1
sys1=function(y){
A=y[1]
B=y[2]
TA=(etaM*(1-exp(-(lambda*A+lambda*(A+B)+2*delta)*tL))-2*lambda*A^2-lambda*A*B)/2/delta
TB=(etaM*exp(-(lambda*A+lambda*(A+B)+2*delta)*tL)*(1-exp(-(lambda*(A+B)+2*delta)*(tH-tL)))-lambda*B^2-lambda*A*B)/2/delta
return(c(TA,TB))
}
FixedPoint(sys1,c(1.90,0.04))
This seems to work:
cc <- capture.output(ff <- FixedPoint(sys1,c(1.90,0.04)),type="message")
where ff now holds the output you want. (Alternately, you could wrap capture.output(...) in invisible() rather than assigning its return value to a variable.)
The problem seems to be that the error message emanates from an un-silence-d try() clause within the package code.
I am trying to understand the way the YourCast R package works and make it work with my data.
For example, if a function produces errors, I
get the source code of that function using YourCast:::bad.fn
add outputs of critical
values at critical stages
use reassignInPackage(name="original.fn", package="YourCast", value="my.fn")
Once I find the cause of the error, I fix it in the function and reassign it in the package.
However, for some strange reason this does not work for non-hidden functions.
For example:
install.packages("YourCast")
Library(YourCast)
YourCast:::check.depvar
This will print the hidden function check.depvar. One line if (all(ix == 1:3)) will produce an error message if any of the x is missing.
Thus, I change the whole function to the following and replace the original formula:
mzuba.check.depvar <- function(formula)
{
return (grepl("log[(]",as.character(formula)[2]))
}
reassignInPackage("check.depvar",
pkgName="YourCast",
mzuba.check.depvar)
rm(mzuba.check.depvar)
Now YourCast:::check.depvar will print my version of that function, and everything is fine.
However
YourCast::yourcast or YourCast:::yourcast or simply yourcast will print the non-hidden function yourcast. Suppose I want to change that function as well.
reassignInPackage(name="yourcast",
pkgName="YourCast",
value=test)
Now, YourCast::yourcast and YourCast:::yourcast will print the new, modified version but yourcast still gives the old version!
That might not a problem if I could simply call YourCast::yourcast instead of yourcast, but that produces some kind of error that I can't trace back because suddenly R-Studio does not print error messages at all anymore!, although it still does something if it is capable to:
> Uagh! do something!
> 1 + 1
[1] 2
> Why no error msg?
>
Restarting the R-session will solve the error-msg problem, though.
So my question is: How do I reassign non-hidden functions in packages?
Furthermore (this would faciliate testing a lot), is there a way to make all hidden functions available without using the ::: operator? I.e., How to export all functions from a package?
I often have the situation like this:
result <- lapply(1:length(mylist), function(x){
doSomething(x)
})
However, if it fails, I have no idea which element in the list failed on doSomething().
So then I end up recoding it as a for loop:
for(i in 1: length(mylist)){
doSomething(mylist[[i]])
}
I can then see the last value of i and what happened. There must be a better way to do this right?? Thanks!
Notice how the error includes 5L
> lapply(1:10, function(i) if (i == 5) stop("oops"))
Error in FUN(1:10[[5L]], ...) : oops
indicating that the 5th iteration failed.
One simple option is to run the code:
options( error=recover )
before running lapply (see ?recover for details).
Then when/if an error occurs you will instantly be put into the recover mode that will let you examine which function you are in, what arguments were passed to that function, etc. so you can see which step you are on and what the possible reason for the error is.
You can also use try or tryCatch as mentioned in the comments to either skip elements that produce an error or print out information on where they occur.
I'm facing a strange issue in R.
Consider the following code (a really simplified version of the real code but still having the problem) :
library(timeSeries)
tryCatch(
{
specificWeekDay <- 2
currTs <- timeSeries(c(1,2),c('2012-01-01','2012-01-02'),
format='%Y-%m-%d',units='A')
# just 2 dates out of range
start <- time(currTs)[2]+100*24*3600
end <- time(currTs)[2]+110*24*3600
# this line returns an empty timeSeries
currTs <- window(currTs,start=start,end=end)
message("Up to now, everything is OK")
# this is the line with the uncatchable error
currTs[!(as.POSIXlt(time(currTs))$wday %in% specificWeekDay),] <- NA
message("I'm after the bugged line !")
},error=function(e){message(e)})
message("End")
When I run that code in RGui, I correctly get the following output:
Up to now, everything is OK
error in evaluating the argument 'i' in
selecting a method for function '[<-': Error in
as.POSIXlt.numeric(time(currTs)) : 'origin' must be supplied
End
Instead, when I run it through RScript (in windows) using the following line:
RScript.exe --vanilla "myscript.R"
I get this output:
Up to now, everything is OK
Execution interrupted
It seems like RScript crashes...
Any idea about the reason?
Is this a timeSeries package bug, or I'm doing something wrong ?
If the latter, what's the right way to be sure to catch all the errors ?
Thanks in advance.
EDIT :
Here's a smaller example reproducing the issue that doesn't use timeSeries package. To test it, just run it as described above:
library(methods)
# define a generic function
setGeneric("foo",
function(x, ...){standardGeneric("foo")})
# set a method for the generic function
setMethod("foo", signature("character"),
function(x) {x})
tryCatch(
{
foo("abc")
foo(notExisting)
},error=function(e)print(e))
It seems something related to generic method dispatching; when an argument of a method causes an error, the dispatcher cannot find the signature of the method and conseguently raises an exception that tryCatch function seems unable to handle when run through RScript.
Strangely, it doesn't happen for example with print(notExisting); in that case the exception is correctly handled.
Any idea about the reason and how to catch this kind of errors ?
Note:
I'm using R-2.14.2 on Windows 7
The issue is in the way the internal C code implementing S4 method dispatch tries to catch and handle some errors and how the non-interactive case is treated in this approach. A work-around should be in place in R-devel and R-patched soon.
Work-around now committed to R-devel and R-patched.
Information about tryCatch() [that the OP already knew and used but I didn't notice]
I think you are missing that your tryCatch() is not doing anything special with the error, hence you are raising an error in the normal fashion. In interactive use the error is thrown and handled in the usual fashion, but an error inside a script run in a non-interactive session (a la Rscript) will abort the running script.
tryCatch() is a complex function that allows the potential to trap and handle all sorts of events in R, not just errors. However by default it is set up to mimic the standard R error handling procedure; basically allow the error to be thrown and reported by R. If you want R to do anything other than the basic behaviour then you need to add a specific handler for the error:
> e <- simpleError("test error")
> tryCatch(foo, error = function(e) e,
+ finally = writeLines("There was a problem!"))
There was a problem!
<simpleError in doTryCatch(return(expr), name, parentenv, handler): object 'foo'
not found>
I suggest you read ?tryCatch in more detail to understand better what it does.
An alternative is to use try(). To modify your script I would just do:
# this is the line with the uncatchable error
tried <- try(currTs[!(as.POSIXlt(time(currTs))$wday %in% specificWeekDay),] <- NA,
silent = TRUE)
if(inherits(tried, "try-error")) {
writeLines("There was an error!")
} else {
writeLines("Everything worked fine!")
}
The key bit is to save the object returned from try() so you can test the class, and to have try() operate silently. Consider the difference:
> bar <- try(foo)
Error in try(foo) : object 'foo' not found
> bar <- try(foo, silent = TRUE)
> class(bar)
[1] "try-error"
Note that in the first call above, the error is caught and reported as a message. In the second, it is not reported. In both cases an object of class "try-error" is returned.
Internally, try() is written as a single call to tryCatch() which sets up a custom function for the error handler which reports the error as a message and sets up the returned object. You might wish to study the R code for try() as another example of using tryCatch().
Many R packages I work with involve functions that give all their messages and warnings through commands to print() calls rather than commands to message() or warning(). I'd like to be able to silence these functions progress indicators, etc, but the standard supressWarnings() or supressMessages doesn't do it. Is there a way I can just suppressPrint?
For example:
silly_developer_function <- function(x){
print("Thanks for using my function!!")
if(is(x, "numeric"))
print("warning, x should be a character")
x
}
I'd like to have a simple function suppressPrint() that I could wrap around a call to this function that would suppress the warning and useless messages (but still print the return value).
Well, those packages are buggy to start with. Use of print() for anything but side-effect in print implementations is a serious mistake.
That said, you can simply use capture.output() to collect the output from such code instead of printing it. So for the above it would be
capture.output(x <- silly_developer_function(...))
print(x)
Another hacky way is to override the default print function. It will affect some functionality, such as printing the body of functions, but objects with their own print methods still get returned as usual.
print <- function(...) {}
> silly_developer_function("a")
[1] "a"
> silly_developer_function(1)
[1] 1