2013-01-14 22 views
5

Mi chiedo se esiste un modo semplice per produrre un gruppo di tabelle o elementi grafici con didascalie variabili in knitr. L'unico modo che conosco è questo: (semplificato da https://github.com/yihui/knitr-examples/blob/master/075-knit-expand.Rnw). Ma è un trascinamento raccogliere l'output in src e quindi stamparlo dopo il ciclo, perché voglio scrivere una funzione per produrre un tale loop da un dataset arbitrario.Loop con didascalie con knitr

\documentclass{article} 
\title{Using knit\_expand() for templates} 
\author{Yihui Xie} 
\begin{document} 

\maketitle 
\tableofcontents 

<<lm-mtcars, tidy.opts=list(width.cutoff=55)>>= 
# the template 
tpl = c("\\subsection{Regression on {{xvar}}}", 
     "<<lm-{{xvar}}>>=", 
     "lm(mpg~{{xvar}}, data=mtcars)", 
     "@") 
# expand to knitr source and pass to knit() 
src = lapply(names(mtcars)[-1], function(xvar) {knit_expand(text = tpl)}) 
@ 

\Sexpr{knit(text = unlist(src))} 

\end{document} 

Quindi quello che voglio essere in grado di fare, invece è qualcosa di simile:

\documentclass{article} 
\title{Using knit\_expand() for templates} 
\author{Yihui Xie} 
\begin{document} 

\maketitle 
\tableofcontents 

<<lm, tidy.opts=list(width.cutoff=55)>>= 
    myLfFun=function(dataset){ 
... some function definition which produces say an lm for each variable in dataset ... 
} 
@ 

\Sexpr{myLfFun(Titanic} 
... 
\Sexpr{myLfFun(mtcars} 
... etc 
\end{document} 

... Che se mi sono imbattuto birra() su di esso produrrebbe ...

\documentclass{article} 
\title{Brew + knitR} 
\author{Ramnath Vaidyanathan} 
\begin{document} 

\maketitle 
\tableofcontents 



<<lm-cyl >>= 
lm(mpg ~ cyl, data = mtcars) 
@ 

<<lm-disp >>= 
lm(mpg ~ disp, data = mtcars) 
@ 

<<lm-hp >>= 
lm(mpg ~ hp, data = mtcars) 
@ 

<<lm-drat >>= 
lm(mpg ~ drat, data = mtcars) 
@ 

<<lm-wt >>= 
lm(mpg ~ wt, data = mtcars) 
@ 

<<lm-qsec >>= 
lm(mpg ~ qsec, data = mtcars) 
@ 

<<lm-vs >>= 
lm(mpg ~ vs, data = mtcars) 
@ 

<<lm-am >>= 
lm(mpg ~ am, data = mtcars) 
@ 

<<lm-gear >>= 
lm(mpg ~ gear, data = mtcars) 
@ 

<<lm-carb >>= 
lm(mpg ~ carb, data = mtcars) 
@ 

((... same for Titanic database ...)) 

\end{document} 

... e l'output di questo potrei quindi knit2pdf(). Quindi, se il modello fosse chiamato tmpl.Rnw, eseguirò brew ('tmpl.Rnw', 'doc.Rnw'); knit2pdf ('doc.Rnw)

+0

Non capisco esattamente cosa mi stai chiedendo: vuoi "tabella variabile/figure didascalie" o "un ciclo per set di dati arbitrari"? In questo esempio non sei limitato a 'mtcars'. –

+0

Grazie. Vorrei "una funzione per un set di dati arbitrario", che includerebbe un ciclo e aggiungerebbe le didascalie appropriate per ciascuna variabile. Io lavoro nella ricerca di sondaggi, quindi ho frequentemente set di dati molto ampi contenenti ciascuno blocchi di variabili correlate che hanno tutti bisogno di essere processati in modo simile (mostra istogrammi e tabelle per ogni variabile nel blocco, ecc.). Ho pensato che questo fosse un caso frequente per Knitr? –

risposta

3

Non vedo perché è necessario knit_expand quando è buono il vecchio sprintf può fare lo stesso. Ecco l'output: http://www.anst.uu.se/chrba104/stackoverflow/output.pdf.

Sebbene il mio modello sia anche personalizzato per il set di dati mtcars, non vedo come si possa semplificare senza perdere flessibilità.

\documentclass{article} 
\title{Not using knit\_expand() for templates} 
\author{Yihui Xie} 
\begin{document} 

\maketitle 
\tableofcontents 

<<lm-mtcars, tidy.opts=list(width.cutoff=55)>>= 
vars <- setdiff(names(mtcars), 'mpg') 
src <- sprintf(
    paste('\\subsection{Regression on %s}', 
      '<<lm-%s>>=', 
      'lm(mpg ~ %s, data=mtcars)', 
      '@', sep='\n'), 
    vars, vars, vars) 
@ 
\Sexpr{knit(text = src)} 

\end{document} 
+0

hai assolutamente ragione, ma non so se questo risponde alla domanda –

+0

Grazie per la risposta, non ci avevo pensato, ma no, non risponde veramente alla domanda. Voglio solo scrivere una funzione myfun = function (someVarsPerhapsWithAttributesForUsingAsCaptions) {... produce ad es. un istogramma di ogni var e usare per es. l'attributo label come didascalia e in realtà lo stampo come lattice, fine della storia} –

+0

Non vedo davvero quello che vuoi fare, ho paura. Ho ragione nel pensare che il tuo esempio (e il mio) ti dia l'output desiderato, ma stai cercando un modo più semplice per scriverlo? – Backlin

3

Io preferisco usare librerie di template dedicati come whisker e brew per raggiungere ciò che si sta cercando, in quanto si cerca di scrivere codice lattice utilizzando una funzione di R IMHO è semplicemente brutto. Il file di modello è mostrato sotto e denominato tpl.Rnw. Puoi trasformarlo in un pdf eseguendo i seguenti comandi. Puoi facilmente scrivere una funzione per incapsulare questa logica che trasforma i modelli di birra in pdf usando knitr.

brew('tpl.Rnw', 'doc.Rnw') 
knit2pdf('doc.Rnw')   

Template File tpl.Rnw

\documentclass{article} 
\title{Brew + knitR} 
\author{Ramnath Vaidyanathan} 
\begin{document} 

\maketitle 
\tableofcontents 


<% for (xvar in names(mtcars)[-1]) { %> 

\subsection{Regression on <%= xvar %>} 

<<lm-<%= xvar %> >>= 
lm(mpg ~ <%= xvar %>, data = mtcars) 
@ 

<% } %> 

\end{document} 
+0

questa è un'altra grande idea, e funziona anche. Ma ancora non so come rendere questi suggerimenti riutilizzabili, cioè per trasformarli in una funzione. –

+0

Puoi pubblicare un esempio migliore, dal momento che non sono sicuro di cosa stai cercando esattamente? Perché non usi il set di dati 'mtcars' e descrivi l'output che stai cercando. Saremo in grado di aiutarti meglio una volta fatto. – Ramnath

+0

Ho seguito il tuo suggerimento e aggiunto alla domanda originale. Ciò che voi tre mi avete aiutato a chiarire è che il mio problema non è in realtà con il ciclo, ma con le funzioni di scrittura da usare con knitr. Grazie! –

0

ho scoperto perché non riuscivo a mettere la linea \Sexpr{knit(text = unlist(src))} all'interno del precedente normale pezzo di codice. Avevo bisogno di impostare opts_knit$set(progress = F, verbose = F) all'inizio del documento e impostare almeno un po 'di comment=NA, warning=FALSE,message=FALSE,echo=FALSE per il blocco. Questa semplice mossa lo rende molto per incollare linee come knit(text = unlist(src)) ovunque io voglia e quante volte voglio in un blocco. Ciò ovvia alla necessità di una funzione dedicata.