How do I permit errors within \Sexpr
?
I have a knitr document. A small part of this document refers to a file that cannot be shared. So whenever \Sexpr{a}
is called on for some object a
that depends on that file being read, it returns an error. I'd like instead for \Sexpr
to print that it encountered an error.
For example,
\documentclass{article}
\usepackage{xcolor} % for red
\begin{document}
<<>>=
x <- 1
@
The value of $x$ is \Sexpr{x}
<<>>=
a <- scan("secret_file.txt")
@
The value of $a$ is \Sexpr{a}.
\end{document}
will not compile (when secret_file.txt
isn't present). I'd like the output to look something like:
I thought that altering the inline
hook would work, but putting the following chunk made no difference.
<<Sexpr-setup>>=
library(knitr)
knit_hooks$set(inline = function(x){
out <- tryCatch(
{
if (is.numeric(x))
x = round(x, getOption("digits"))
paste(as.character(x), collapse = ", ")
},
error = function(cond){
return("\\textcolor{red}{\\textbf{Sexpr error!}}")
invisible(NULL)
},
warning = function(cond){
return("\\textcolor{red}{\\textbf{Sexpr warning!}}")
invisible(NULL)
}
)
return(out)
})
@
It is not essential to have a custom error message, only that errors are clear from the output and do not prevent compilation. I appreciate that I could do a find replace into something like \Sexpr{XX(
and define a function upfront XX()
that does the same tryCatch
maneouvre, but I thought knitr
could do this.
Calling knitr::knit
on the above and applying the traceback shows that:
11: eval(expr, envir, enclos)
10: eval(parse_only(code[i]), envir = envir)
9: withVisible(eval(parse_only(code[i]), envir = envir))
8: inline_exec(block)
7: in_dir(opts_knit$get("root.dir") %n% input_dir(), inline_exec(block))
6: call_inline(x)
5: process_group.inline(group)
4: process_group(group)
3: withCallingHandlers(if (tangle) process_tangle(group) else process_group(group),
error = function(e) {
setwd(wd)
cat(res, sep = "\n", file = output %n% "")
message("Quitting from lines ", paste(current_lines(i),
collapse = "-"), " (", knit_concord$get("infile"),
") ")
})
2: process_file(text, output)
1: knitr::knit("knitr-prevent-errors.Rnw", quiet = TRUE)
From following the functions, it appears that the error is low down at
eval(parse_only(code[i]), envir = envir)
Where code[i]
is a
. Am I right in thinking that the only way to resolve this is to change the line starting v =
with a tryCatch
?
With the option include=FALSE
in the setup chunk,the following worked for me with output as below. If it does not work for you I will delete the post
\documentclass{article}
\usepackage{xcolor} % for red
<<setup, include=FALSE>>=
knit_hooks$set(inline = function(x) {
out <- tryCatch(
{
if (is.numeric(x))
x = round(x, getOption("digits"))
paste(as.character(x), collapse = ", ")
},
error = function(cond){
return("\\textcolor{red}{\\textbf{Sexpr error!}}")
invisible(NULL)
},
warning = function(cond){
return("\\textcolor{red}{\\textbf{Sexpr warning!}}")
invisible(NULL)
}
)
return(out)
})
@
\begin{document}
<<>>=
x <- 1
@
The value of $x$ is \Sexpr{x}
<<>>=
a <- scan("secret_file.txt")
@
The value of $a$ is \Sexpr{a}.
\end{document}
Knitr Output:
>knitr::knit("test.Rnw")
processing file: test.Rnw
|......... | 14%
ordinary text without R code
|................... | 29%
label: setup (with options)
List of 2
$ include: logi FALSE
$ indent : chr " "
|............................ | 43%
ordinary text without R code
|..................................... | 57%
label: unnamed-chunk-1 (with options)
List of 1
$ indent: chr " "
|.............................................. | 71%
inline R code fragments
|........................................................ | 86%
label: unnamed-chunk-2 (with options)
List of 1
$ indent: chr " "
|.................................................................| 100%
inline R code fragments
output file: test.tex
[1] "test.tex"
Tex Output:
>texi2pdf("test.tex")
>
I am using MikTex 2.9,knitr 1.9, R 3.0.2 on Windows , can you please attach your log files then we can compare the differences if any
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With