I've written the following code:
extract_distract <- function(dataset, type="increase"){
if(dataset = wfh){
if(type = "decrease"){
decr_distract <- str_subset(decr_product, "distract")
str_extract(decr_distract, ".{0,30}distract+.{0,30}")
} else if(type = "increase"){
incr_distract <- str_subset(incr_product, "distract")
str_extract(incr_distract, ".{0,30}distract+.{0,30}")
} else{stop("NA - use either increase or decrease type")}
} else{stop("NA - use (dataset = wfh)")}}
Everytime i try to run it it gives me the following error:
> } else{stop("NA - use either increase or decrease type")}
Error: unexpected '}' in " }"
> } else{stop("NA - use (dataset = wfh)")}}
Error: unexpected '}' in " }"
I am new to this but would appreciate any help
It's generally a good idea to pay most attention to the first error, not the last ones. If I run your code, I see
> extract_distract <- function(dataset, type="increase"){
+ if(dataset = wfh){
Error: unexpected '=' in:
"extract_distract <- function(dataset, type="increase"){
if(dataset ="
> if(type = "decrease"){
Error: unexpected '=' in " if(type ="
> decr_distract <- str_subset(decr_product, "distract")
Error in str_subset(decr_product, "distract") :
could not find function "str_subset"
> str_extract(decr_distract, ".{0,30}distract+.{0,30}")
Error in str_extract(decr_distract, ".{0,30}distract+.{0,30}") :
could not find function "str_extract"
> } else if(type = "increase"){
Error: unexpected '}' in " }"
> incr_distract <- str_subset(incr_product, "distract")
Error in str_subset(incr_product, "distract") :
could not find function "str_subset"
> str_extract(incr_distract, ".{0,30}distract+.{0,30}")
Error in str_extract(incr_distract, ".{0,30}distract+.{0,30}") :
could not find function "str_extract"
> } else{stop("NA - use either increase or decrease type")}
Error: unexpected '}' in " }"
> } else{stop("NA - use (dataset = wfh)")}}
Error: unexpected '}' in " }"
The first error is Error: unexpected '=' in: ..., which would have led you to the solution mentioned by #GregorThomas: you should have used ==, not =. The reason this caused all the other errors is that R discards the incorrect lines. After they are gone, the rest of your code doesn't make sense.
Related
I would to take five parametrs: a, b, c, d and mean of standards deviation from every model (it is a normal value, no matrix) and store this information as a vector, then using rbind to crate matrix which I can search for the models and parameters.
I was trying with nested loops like:
for (a in 0:2){
for (b in 0:2){
for (c in 1:2){
for (d in 1:2){
Garch_model <- garchFit(~arma(a,b)+garch(c,d), include.mean = TRUE,cond.dist = c("norm"),data = dax_data)
ValidationBox <- rbind(ValidationBox,c(a,b,c,d,mean(Garch_model#sigma.t))
}
}
}
}
but I'm getting this error:
Error: unexpected '}' in: " ValidationBox <-
rbind(ValidationBox,c(a,b,c,d,mean(Garch_model#sigma.t))
}"
} Error: unexpected '}' in " }"
} Error: unexpected '}' in " }"
} Error: unexpected '}' in "}"
Can anyone tell me what's the issue?
Displaying error locations with options(show.error.locations = TRUE) doesn't seem to work when handling exceptions with tryCatch. I am trying to display location of the error but I don't know how:
options(show.error.locations = TRUE)
tryCatch({
some_function(...)
}, error = function (e, f, g) {
e <<- e
cat("ERROR: ", e$message, "\nin ")
print(e$call)
})
If I then look at the variable e, the location doesn't seem to be there:
> str(e)
List of 2
$ message: chr "missing value where TRUE/FALSE needed"
$ call : language if (index_smooth == "INDEX") { rescale <- 100/meanMSI[plotbaseyear] ...
- attr(*, "class")= chr [1:3] "simpleError" "error" "condition"
If I don't trap the error, it is printed on the console along with source file and line number. How to do it with tryCatch?
Context
As noted by Willem van Doesburg, it is not possible to use the traceback() function to display where the error occured with tryCatch(), and to my knowledge there is currently no practical way to store the position of the error with base functions in R while using tryCatch .
The idea of a separate error handler
The possible solution I found consists of two parts, the main one is writing an error handler similar to that of Chrispy from "printing stack trace and continuing after error occurs in R" which produces a log with the position of the error.
The second part is capturing this output into a variable, similarly to what was suggested by Ben Bolker in "is it possible to redirect console output to a variable".
The call stack in R seems to be purged when an error is raised and then handled (I might be wrong so any information is welcomed), hence we need to capture the error while it is occuring.
Script with an error
I used an example from one of your previous questions regarding where and R error occured with the following function stored in a file called "TestError.R" which I call in my example bellow:
# TestError.R
f2 <- function(x)
{
if (is.null(x)) "x is Null"
if (x==1) "foo"
}
f <- function(x)
{
f2(x)
}
# The following line will raise an error if executed
f(NULL)
Error tracing function
This is the function I adapted form Chrispy's code as I mentionned above.
Upon execution, if an error is raised, the code underneath will print where the error occured, in the case of the above function, it will print :
"Error occuring: Test.R#9: f2(x)" and "Error occuring: Test.R#14: f(NULL)" meaning the error result from a trouble with the f(NULL) function at line 14 which references the f2() function at line 9
# Error tracing function
withErrorTracing = function(expr, silentSuccess=FALSE) {
hasFailed = FALSE
messages = list()
warnings = list()
errorTracer = function(obj) {
# Storing the call stack
calls = sys.calls()
calls = calls[1:length(calls)-1]
# Keeping the calls only
trace = limitedLabels(c(calls, attr(obj, "calls")))
# Printing the 2nd and 3rd traces that contain the line where the error occured
# This is the part you might want to edit to suit your needs
print(paste0("Error occuring: ", trace[length(trace):1][2:3]))
# Muffle any redundant output of the same message
optionalRestart = function(r) { res = findRestart(r); if (!is.null(res)) invokeRestart(res) }
optionalRestart("muffleMessage")
optionalRestart("muffleWarning")
}
vexpr = withCallingHandlers(withVisible(expr), error=errorTracer)
if (silentSuccess && !hasFailed) {
cat(paste(warnings, collapse=""))
}
if (vexpr$visible) vexpr$value else invisible(vexpr$value)
}
Storing the error position and the message
We call the script TestError.R above and capture the printed output in a variable, here called errorStorage with which we can deal later on or simply display.
errorStorage <- capture.output(tryCatch({
withErrorTracing({source("TestError.R")})
}, error = function(e){
e <<- e
cat("ERROR: ", e$message, "\nin ")
print(e$call)
}))
Hence we keep the value of e with the call and message as well as the position of the error location.
The errorStorage output should be as follow:
[1] "[1] \"Error occuring: Test.R#9: f2(x)\" \"Error occuring: Test.R#14: f(NULL)\""
[2] "ERROR: argument is of length zero "
[3] "in if (x == 1) \"foo\""
Hoping this might help.
You can use traceback() in the error handler to show the call stack. Errors in a tryCatch don't produce line numbers. See also the help on traceback. If you use your tryCatch statements defensively, this will help you narrow down the location of the error.
Here is a working example:
## Example of Showing line-number in Try Catch
# set this variable to "error", "warning" or empty ('') to see the different scenarios
case <- "error"
result <- "init value"
tryCatch({
if( case == "error") {
stop( simpleError("Whoops: error") )
}
if( case == "warning") {
stop( simpleWarning("Whoops: warning") )
}
result <- "My result"
},
warning = function (e) {
print(sprintf("caught Warning: %s", e))
traceback(1, max.lines = 1)
},
error = function(e) {
print(sprintf("caught Error: %s", e))
traceback(1, max.lines = 1)
},
finally = {
print(sprintf("And the result is: %s", result))
})
apparently try and trycatch do not work for this problem! Any alternative solutions?
i'm trying to make the following example code work without actually changing any code
result = 0
for(i in 1:10){
result = result + i
log("a") #I do not care about this error
result = result + i
}
This should give result = 110
If i actually do it manually by copying the part inside the loop and increasing the counter it works perfectly:
result = 0
#iteration 1
i = 1
result = result + i
log("a")
result = result + i
#iteration 2
i = i+1
result = result + i
log("a")
result = result + i
#iteration 3
i = i+1
result = result + i
log("a")
result = result + i
#etc.
However my real code has about 1000 lines and needs to loop a few hundred times.
So i'd like to have some option
options(on.error.just.continue.the.next.line) = TRUE
I've read about try/tryCatch but I don't understand it correctly I think
If you just want the code to run, you can use try instead:
result <- 0
for(i in 1:10){
result = result + i
try({log("a")}) #I do not care about this error
result = result + i
}
Error in log("a") : non-numeric argument to mathematical function
Error in log("a") : non-numeric argument to mathematical function
Error in log("a") : non-numeric argument to mathematical function
Error in log("a") : non-numeric argument to mathematical function
Error in log("a") : non-numeric argument to mathematical function
Error in log("a") : non-numeric argument to mathematical function
Error in log("a") : non-numeric argument to mathematical function
Error in log("a") : non-numeric argument to mathematical function
Error in log("a") : non-numeric argument to mathematical function
Error in log("a") : non-numeric argument to mathematical function
result
[1] 110
To turn off the message, use
try({log("a")}, silent=TRUE)
If you are worried about a larger block of code, you can wrap it in { } as follows:
result <- 0
for(i in 1:10){
try({ # start code block
result = result + i
log("a") # I do not care about this error
result = result + i
}, silent=TRUE) # end of try function
}
result
[1] 55
Here, the first assignment to result completes in the for loop. Then the error occurs which "wipes out" the execution of the rest of the code block, which is the second assignment here. However, the loop execution is allowed to continue through completion.
You can try using a try catch block:
result = 0
for (i in 1:10) {
result = result + i
tryCatch({
log("a") #I do not care about this error
}, warning = function(w) {
# comment out the next print statement for a silent warning
print("warning")
}, error = function(e) {
# comment out the next print statement for a silent error
print("error")
}, finally = {
# cleanup
}
result = result + i
}
I want to capture an error from D%4 and move on. The error is:
Error: unexpected input in "D%4"
Typically if a function is being called the following works:
capture_warn_error <- function(x){
tryCatch({
x
}, warning = function(w) {
w
}, error = function(e) {
e
})
}
capture_warn_error(D%4)
But the no recovery is possible as `D%4 shuts down everything immediately:
## > capture_warn_error(D%4)
## Error: unexpected input in "capture_warn_error(D%4)"
Is there anyway to capture such a stubborn beast and move on? I know D%4 isn't an object but this works for other non objects:
capture_warn_error(means)
## <simpleError in doTryCatch(return(expr), name, parentenv, handler): object 'means' not found>
It's be nice to:
Understand why D%4 is unrecoverable vs means
Find a way to recover still and capture D%4's error
As others have stated it is because text typed at the console gets passed to the parser. D%4 fails the rigid test of being valid R expression, because a single % is not valid inside an R name (although it would create a token that would be interpreted as a user defined function if there were a closing %) and % is also not a function name (although%% is). The error occurs in the processing of the argument to your function and so it never reached the internal tryCatch-call. I originally didn't get the idea that you wanted to parse this input as R code, so thought that simply wrapping readline as the single argument to be be input may satisfy:
mfun <- function( x=readline(">>+ ") ){ print(x) }
mfun()
#-----screen will display--------
>>+ D%4
[1] "D%4"
If I'm wrong about your intent, as it appears on a re-read of the question, then this would build that input mechanism into your capture_error function. This brings those characters in as unparsed text and then does the parse-eval within the tryCatch enclosure:
> capture_warn_error <- function(x=readline(">>+ ")){
+ tryCatch({ eval(parse(text=x))
+
+ }, warning = function(w) {
+ w
+ }, error = function(e) {
+ e
+ })
+ }
> capture_warn_error(D%4)
Error: unexpected input in "capture_warn_error(D%4)"
> capture_warn_error()
>>+ D%4
<simpleError in parse(text = x): <text>:1:2: unexpected input
1: D%4
^>
> err <- capture_warn_error()
>>+ D%4
> err
<simpleError in parse(text = x): <text>:1:2: unexpected input
1: D%4
^>
> err <- capture_warn_error()
>>+ D %% 4
> err
<simpleError in D%%4: non-numeric argument to binary operator>
> err <- capture_warn_error()
>>+ 4 %smthg% 2
> err
<simpleError in eval(expr, envir, enclos): could not find function "%smthg%">
As demonstrated above, it does require that you not provide any input in the argument list to the function call, but rather make the capture-call with an empty argument list.
You could set up a function to capture input and parse it, wrapping it in your capture_warn_error function.
getfunction <- function(){
x<-readline()
if(x == "exitnow"){return("bye!")}
print(capture_warn_error(eval(parse(text = x))))
getfunction()
}
They'll now be typing at a non-console prompt, but it will work okish - assignments will need work.
1+1
[1] 2
d%e
<simpleError in parse(text = x): <text>:1:2: unexpected input
1: d%e
^>
exitnow
[1] "bye!"
I think this works for capturing the error, although it's a bit convoluted.
a <- try(eval(parse(text="D%4")))
I am unable to supress the error,though my pdf file is getting converted into text but i am unable to suppress this error.
tryCatch(system(paste("\"", exe, "\" \"", dest, "\"", sep = ""), wait = T))
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
> suppressWarnings(system(paste("\"", exe, "\" \"", dest, "\"", sep = ""), wait = T))
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
>tryCatch(system(paste("\"", exe, "\" \"", dest, "\"", sep = ""), wait = T), error = function(e) e)
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
> suppressMessages(system(paste("\"", exe, "\" \"", dest, "\"", sep = ""), wait = T))
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
> tryCatch(suppressWarnings(capture.output(system(paste("\"", exe, "\" \"", dest, "\"", sep = ""), wait = T))), error = function(e) e)
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
character(0)
> tryCatch({system(paste("\"", exe, "\" \"", dest, "\"", sep = ""), wait = T)}, error = function(e) e)
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Any reason why am i unable to suppress it ? how can i get rid of this error ?Thanks.
EDIT
With silent=TRUE and function(e){invisible(e)}
tryCatch(system(paste("\"", exe, "\" \"", dest, "\"", sep = ""), wait = T), error = function(e){invisible(e)})
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
> try(system(paste("\"", exe, "\" \"", dest, "\"", sep = ""), wait = T),silent=TRUE)
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
Syntax Error: Missing or invalid 'Bounds' entry in stitching function
EDITED
It stopped the error but it has also stopped the functionality as well,The pdf file is not getting converted into text by this.
tryCatch(system2(paste("\"", exe, "\" \"", dest, "\"", sep = ""), wait = TRUE,
stdout=TRUE, stderr=TRUE),
error=function(err) NA)
[1] NA
source code
dest=paste("C:/wamp/www/LU/my/pdffiles",file_list[i],sep="/")
exe <- "C:\\Program Files\\xpdfbin-win-3.03\\bin32\\pdftotext.exe"
try(system(paste("\"", exe, "\" \"", dest, "\"", sep = ""), wait = TRUE),
silent=TRUE)
Normally one would write
tryCatch({
system("xyz")
}, error=function(err) {
## do something with 'err', then maybe throw it again stop(err)
## or providing an alternative return value
NA
})
So
> xx = tryCatch(stop("oops"), error=function(err) NA)
> xx
[1] NA
but it seems that some errors thrown by system() cannot be caught in this way.
> xx = tryCatch(system("foobar"), error=function(err) NA)
sh: 1: foobar: not found
The hint that something might be done is from the value of xx:
> xx
[1] 127
The help page first points us to system2() instead, where we see
If 'stdout = TRUE' or 'stderr = TRUE', a character vector giving
the output of the command, one line per character string. (Output
lines of more than 8095 bytes will be split.) If the command
could not be run an R error is generated.
and sure enough
> tryCatch(system2("foobar", stdout=TRUE, stderr=TRUE), error=function(err) NA)
[1] NA
Never actually used tryCatch() before but it seems your error function is error=function(e) e so you are just returning the error you get.
I have used try() in the past with option silent=TRUE to avoid showing the error message. Something like this (disclaimer, the help page for try mentions that using tryCatch may be more efficient):
res=try(runif(Inf), silent=TRUE)
if(class(res)=="try-error") {
print("some error happened")
} else {
print(res)
}
res=try(runif(10), silent=TRUE)
if(class(res)=="try-error") {
print("some error happened")
} else {
print(res)
}
There may be better ways to do this and hopefully others will correct my solution.