2016-04-13 18 views
9

Jak mogę zezwalać na błędy w obrębie \Sexpr?Obsługa błędów w obrębie Sexpr

Mam dokument dziewiarskich. Niewielka część tego dokumentu odnosi się do pliku, którego nie można udostępnić. Tak więc, gdy \Sexpr{a} jest wywoływany dla jakiegoś obiektu a, który zależy od tego pliku, który jest czytany, zwraca błąd. Zamiast tego chciałbym, aby \Sexpr wydrukowało, że napotkało błąd.

Przykładowo

\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} 

nie kompilacji (gdy secret_file.txt nie jest obecna). Chciałbym, żeby wyjście wyglądało jak: Sexpr-error-detected

Myślałem, że zmiana haczyka inline zadziała, ale wprowadzenie następującego fragmentu nie robi różnicy.

<<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) 
}) 
@ 

Nie jest istotne, aby mieć niestandardowy komunikat o błędzie, tylko że błędy są jasne na wyjściu i nie uniemożliwiają kompilacji. Doceniam to, że mogłem zrobić zamianę na coś podobnego do \Sexpr{XX( i zdefiniować funkcję z góry XX(), która wykonuje ten sam manewr tryCatch, ale pomyślałem knitr could do this.


Wywołanie knitr::knit na powyższe i stosowania traceback pokazuje, że:

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) 

Od następujące funkcje, wydaje się, że błąd jest nisko na

eval(parse_only(code[i]), envir = envir) 

Gdzie code[i] jest a. Czy mam rację, sądząc, że jedynym sposobem rozwiązania tego problemu jest zmiana linii zaczynającej się v = z ?

+0

Nie wiesz, czy odpowiedź [tutaj] (https://stackoverflow.com/questions/ 24978427/suppressing-error-messages-in-knitr) może być dostosowany do twojego problemu. Odpowiedź Josha O'Briena zmienia funkcję zawieszania błędów. Dokumentacja knitr [here] (http://yihui.name/knitr/hooks/) sugeruje, że ten hak obsługuje błędy zarówno dla porcji, jak i kodu śródliniowego. 'error: errors from stop() (dotyczy błędów w obu częściach kodu i wbudowanym kodzie R)'.Miałem szybką grę z dodaniem 'knit_hooks $ set (error = myErrorFunction)' z twoim kodem, ale nadal nie mogłem go skompilować z '\ Sexpr {a}'. – Graeme

+0

Dzięki. Tak, to będzie działać tylko w przypadku opcji partycji. – Hugh

Odpowiedz

5

Z opcją include=FALSE w porcji instalacyjnej, poniżej pracował dla mnie z wyjściem jak poniżej. Jeśli to nie działa dla ciebie będę usunąć posta

enter image description here

\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 wyjściowa:

>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 wyjściowa:

>texi2pdf("test.tex") 
> 

jestem za pomocą MikTex 2.9, knitr 1.9, R 3.0.2 w systemie Windows, czy możesz dołączyć pliki dziennika, a następnie możemy porównać różnice, jeśli takie są,

+0

Więc nie udało mi się go skompilować, ale chciałbym zbadać to nieco więcej. Co otrzymasz, gdy "knitr :: knit" plik? – Hugh

+0

to nie działa dla mnie – rawr

+0

Jak to działa, bez 'library (knitr)' w 'test.Rnw'? – Hugh