2014-06-30 8 views
5

Sto tentando di scrivere un riassunto per un documento dinamico, ma le mie chiamate \Sexpr{} non funzionano.Come forzare Knitr a valutare Sexpr dopo tutti gli altri blocchi di codice

In sostanza, tutto ciò che sto tentando di fare è avviare il documento con un abstract con valori p generati da \Sexpr{value} dove il valore è determinato "a valle" nel documento. Per esempio

Questo funziona:

\begin{document} 

<<foo>>= 
    value = 10 
@ 

Today I bought \Sexpr{value} Salamanders 

\end{document} 

questo non funziona (e quello che sto cercando di realizzare)

\begin{document} 

Today I bought \Sexpr{value} Salamanders 

<<foo>>= 
    value = 10 
@ 
+0

probabilmente dovrete eseguire due passaggi attraverso il documento, salvare il roba che vuoi dai calcoli successivi, e ricaricarlo all'inizio. –

+0

È normale. Nel tuo primo esempio hai definito "valore" prima di chiamarlo in \ Sexpr {}; quindi esiste nel tuo spazio di lavoro e può essere chiamato. E nel tuo secondo esempio chiami variabile inesistente; quindi devi prima definirlo o caricare uno spazio di lavoro in cui esiste. –

risposta

3

non vedo una soluzione semplice di rinviare la valutazione di \Sexpr dopo valutazione dei blocchi di codice, ma è ancora facile da usare \Sexp con valori definiti successivamente, ad esempio, un abstract: utilizzare un file separato (myabstract.Rnw) per l'abstract, aggiungere \input{myabstract} dove l'abstract è suppo sed da includere e knitmyabstract.Rnw alla fine del documento principale:

document.Rnw:

\documentclass{article} 
\begin{document} 

\begin{abstract} 
    \input{myabstract} 
\end{abstract} 

Main text. 

<<>>= 
answer <- 42 
@ 

\end{document} 

<<include = FALSE>>= 
knit("myabstract.Rnw") 
@ 

myabstract.Rnw:

The answer is \Sexpr{answer}. 

chiave per capire come questo funziona è quello di rendersi conto che knitr elabora il documento prima che LaTeX lo faccia. Pertanto, non importa che il comando LaTeX \input{myabstract} includa myabstract.tex "prima" (non riferendosi all'ora ma facendo riferimento al numero di riga), knit("myabstract.Rnw") genera myabstract.tex.


Per scenari più complessi, la valutazione e l'uscita potrebbe essere separati: fare tutti i calcoli nei primi pezzi e stampare i risultati a cui appartengono. Per mostrare il codice sorgente, blocchi reuse (impostazione eval = FALSE). Utilizzando l'esempio dall'alto, il che significa:

\documentclass{article} 
\begin{document} 

<<calculation, include = FALSE>>= 
answer <- 42 
@ 

\begin{abstract} 
    The answer is \Sexpr{answer}. 
\end{abstract} 

Main text. 

<<calculation, eval = FALSE>>= 
@ 

\end{document} 
+0

Avevo immaginato che potesse esserci un modo per aggiungere un comando 'eval' che memorizzava nella cache il chuck per un' \ Sexp' più in alto. Se capisco che Knitr sta utilizzando Latexmk per eseguire il codice LaTeX (più volte)? –

+0

Nessun latexmk o più esecuzioni non sono coinvolti. I pezzi nel documento.Rnw sono eseguiti uno per uno nell'ordine indicato. L'ultimo di questi pezzi lavora a maglia myabstract.Rnw a myabstract.tex (provalo!). Si noti che tutti gli oggetti disponibili nell'ambiente in cui viene chiamato knit() sono disponibili nel documento che viene lavorato a maglia. Pertanto, l'oggetto 'answer' è disponibile quando si lavora a maglia myabstract.Rnw. Dopo che tutta la lavorazione è terminata, la solita toolchain TEX compila mydocument.tex in PDF. A quel punto, myabstract.tex esiste e può essere incluso dove appropriato. –

+0

Grazie, questo è molto utile. –

1

Da un punto di vista intuitivo ha senso che questo genera un errore: come si può parlare del valore di un oggetto che deve ancora essere calcolato?

Una possibile soluzione è quella di eseguire il codice pezzo prima, ma hanno include=FALSE e quindi riutilizzare il codice pezzo in seguito, vedere Chunk Reference/Macro: How to reuse chunks | knitr

\begin{document} 

%%# Code is evaluated but nothing is written in the output 
<<foo, include=FALSE>>= 
    value = 10 
    plot(sin) 
    rnorm(5) 
@ 

Today I bought \Sexpr{value} Salamanders 

%%# Here code can be included in the output (figure, echo, results etc.) 
<<bar>>= 
<<foo>> 
@ 

\end{document} 
+0

Non sapevo che potessi riciclare pezzi come questo. Grazie per la risposta. –

+0

@Eric Si noti che esiste una sintassi più compatta per il riutilizzo di blocchi, consultare la pagina della documentazione di riferimento o la seconda parte della mia risposta sopra. –

Problemi correlati