петли с надписями с лицевой

Мне интересно, есть ли простой способ создать кучу таблиц или графиков с переменными заголовками в knitr. Единственный способ, который я знаю, таков: //github.com/yihui/knitr-examples/blob/master/075-knit-expand.Rnw). Но собирать выходные данные в src, а затем печатать их после цикла — это хлопотно, потому что я хочу написать функцию для создания такого цикла из произвольного набора данных.

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

Итак, вместо этого я хочу иметь возможность сделать что-то вроде этого:

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

... Что, если бы я запустил brew() на нем, выдал бы...

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

... и вывод этого я мог бы потом связать2pdf(). Итак, если бы шаблон назывался tmpl.Rnw, я бы запустил brew('tmpl.Rnw','doc.Rnw');knit2pdf('doc.Rnw)


person Steve Powell    schedule 14.01.2013    source источник
comment
Я не понимаю, что именно вы спрашиваете - вам нужны переменные подписи к таблицам/рисункам или цикл для произвольного набора данных? В этом примере вы не ограничены mtcars.   -  person Yihui Xie    schedule 15.01.2013
comment
Спасибо. Я хотел бы функцию для произвольного набора данных, которая включала бы цикл и добавляла бы соответствующие подписи для каждой переменной. Я занимаюсь исследованиями в области опросов, поэтому у меня часто есть очень большие наборы данных, каждый из которых содержит блоки связанных переменных, которые все нуждаются в одинаковой обработке (показывать гистограммы и таблицы для каждой переменной в блоке и т. д.). Я думал, что это частый случай использования для вязания?   -  person Steve Powell    schedule 16.01.2013


Ответы (3)


Я не понимаю, зачем вам нужен knit_expand, когда старый добрый sprintf может сделать то же самое. Вот результат: http://www.anst.uu.se/chrba104/stackoverflow/output.pdf.

Хотя мой шаблон также создан специально для набора данных mtcars, я не вижу, как можно упростить его, не теряя при этом гибкости.

\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}
person Backlin    schedule 14.01.2013
comment
вы абсолютно правы, но я не знаю, отвечает ли это на вопрос - person Yihui Xie; 15.01.2013
comment
Спасибо за ответ, я не думал об этом, но нет, это не совсем ответ на вопрос. Я просто хочу написать функцию myfun=function(someVarsPerhapsWithAttributesForUsingAsCaptions){... произвести, например. гистограмму каждой переменной и использовать, например. атрибут label в качестве подписи и на самом деле распечатать его как латекс, конец истории} - person Steve Powell; 15.01.2013
comment
Я действительно не понимаю, что вы хотите сделать, я боюсь. Правильно ли я думаю, что ваш пример (и мой) дает вам желаемый результат, но вы ищете более простой способ его написать? - person Backlin; 15.01.2013
comment
Спасибо - да, оба примера дают мне желаемый результат. Но я хочу, чтобы результат был напечатан до конца фрагмента, поэтому мне не нужен \Sexpr{knit(text = src)} вне фрагмента. Это все потому, что я просто хочу написать функцию для использования с Knitr, которая либо а) будет перебирать некоторые переменные и печатать таблицы и/или графику на основе каждой переменной с их заголовками, либо б) может использоваться внутри цикла и будет печатать таблицы и/или графику для одного var и его заголовка. Ни в одном примере это не достигается из-за необходимости отдельного \Sexpr в конце. Надеюсь, теперь я понятен ;-) - person Steve Powell; 15.01.2013
comment
Спасибо, я понимаю, что вы хотите сделать сейчас, но не почему. Является ли проблема A) в том, что бывают ситуации, когда построение вектора символов и вызов \Sexpr не могут дать то, что вы хотите, или B) в том, что это утомительно делать, когда шаблон становится длинным? Возможно несколько страниц с большим количеством рисунков, таблиц и текста. - person Backlin; 15.01.2013
comment
В основном B, поэтому мне нужно написать функцию для цикла (и, возможно, также вызвать эту функцию из цикла более высокого уровня). Я занимаюсь исследованиями в области опросов, поэтому у меня часто есть очень большие наборы данных, которые все нуждаются в одинаковой обработке. Я предполагаю, что это частый случай использования для вязания? Если бы я только мог поместить knit(text = src) внутри чанка, а не после него, но если я поставлю его внутри чанка, я просто получу мусор. - person Steve Powell; 15.01.2013
comment
Понятно... К сожалению, я не могу понять, как это сделать. Лично я бы просто обходился тем, что у вас уже есть. - person Backlin; 16.01.2013

Я предпочитаю использовать специальные библиотеки шаблонов, такие как whisker и brew, чтобы достичь того, что вы ищете, поскольку попытка написать латексный код с использованием функции R, ИМХО, просто уродлива. Файл шаблона показан ниже и называется tpl.Rnw. Вы можете превратить его в PDF, выполнив следующие команды. Вы можете легко написать функцию для инкапсуляции этой логики, которая преобразует шаблоны варки в pdf с помощью Knitr.

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

Файл шаблона 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}
person Ramnath    schedule 15.01.2013
comment
это еще одна отличная идея, и она также работает. Но я до сих пор не знаю, как сделать любое из этих предложений многоразовым, то есть превратить его в функцию. - person Steve Powell; 16.01.2013
comment
Можете ли вы опубликовать лучший пример, так как я не понимаю, что именно вы ищете? Почему бы вам не использовать набор данных mtcars и не описать результат, который вы ищете. Мы сможем помочь вам лучше, как только вы это сделаете. - person Ramnath; 16.01.2013
comment
Я последовал вашему предложению и добавил к исходному вопросу. Вы трое помогли мне прояснить, что моя проблема на самом деле не в цикле, а в написании функций для использования с Knitr. Спасибо! - person Steve Powell; 16.01.2013
comment
Детали помогают. Я до сих пор не понимаю, что возвращает ваша функция. Можете ли вы написать простую функцию, использующую mtcars, чтобы показать нам, каковы результаты. Я считаю, что решения действительно просты, как только вы предоставите образец функции. - person Ramnath; 16.01.2013

Я выяснил, почему я не мог поместить строку \Sexpr{knit(text = unlist(src))} в предыдущий кусок нормального кода. Мне нужно было установить opts_knit$set(progress = F, verbose = F) в начале документа и установить хотя бы часть comment=NA, warning=FALSE,message=FALSE,echo=FALSE для чанка. Это простое действие позволяет вставлять такие строки, как knit(text = unlist(src)), куда угодно и сколько угодно раз в блоке. Это устраняет необходимость в специальной функции.

person Steve Powell    schedule 30.01.2013