2014-02-10 3 views
11

Я создаю отчет о латексе, который производит несколько графиков в вызове dlply. Разумеется, вызов dlply в одном блоке и для того, чтобы получить метки и титры для изменения, я использую фрагмент от Steve Powell ниже. Подход работает, но кажется, что knitr не корректно форматирует вывод. Простой пример, который демонстрирует:наряды, надписи и надписи внутри одного куска

\documentclass{article} 

\begin{document} 
<startup,echo=FALSE,results='hide',message=FALSE,tidy=FALSE,warning=FALSE,fig.keep='all',comment=NA>>= 
require(knitr) 
require(ggplot2) 
opts_knit$set(progress = F, verbose = F) 
opts_chunk$set(comment=NA, 
      tidy=FALSE, 
      warning=FALSE, 
      message=FALSE, 
      echo=FALSE, 
      dpi=600, 
      fig.width=6.75, fig.height=4, # Default figure widths 
      dev=c("pdf",'tiff'), 
      dev.args=list(pdf=list(NULL),tiff=list(compression='lzw')), 
      error=FALSE) 
@ 
<<plotloop,results='asis'>>= 
for(x in seq(1,20)){ 
    x1<-data.frame(x=seq(1,10),y=seq(1,10)) 
    plt<-ggplot(data=x1,aes(x,y))+geom_point() 
    figLabel=paste('Figure',x,sep='') 
    capt<-paste('Caption for fig.',x) 
    cat(knit(text=(paste("<<",figLabel,",fig.pos='ht',fig.cap='",capt,"'>>=\nplt\[email protected]",sep='')))) 
} 
@ 
\end{document} 

Это почти работает. Беда в том, что knitr помещает закрывающий \ титры скобки вне \ этикеточной скобы, которую можно увидеть в фрагменте коды из файла .tex ниже:

\begin{knitrout} 
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969} 
\color{fgcolor} 
\begin{figure}[ht] 
\includegraphics[width=\maxwidth]{figure/Figure1} \caption[Caption for fig]{Caption for fig. 1\label{fig:Figure1}} 
\end{figure} 
\end{knitrout} 

латекса может справиться с этим, если есть только несколько цифр, как это но с большим количеством графиков он начинает неправильно размещать их. Я также попытался это с

fig.cap=paste('testLoop',seq(1,20)) 

подход и получить тот же результат.

Дальнейшее уточнение: я нашел это на wikipedia's Latex/Floats... странице:

Если вы хотите, чтобы маркировать фигуру, так что вы можете ссылаться на него позже, вы должны добавить метку после заголовка (внутри, кажется, работает в LaTeX 2e), но внутри плавающей среды. Если он объявлен снаружи, он даст номер раздела.

«Ядро, похоже, работает в LaTeX 2e», привлекло мое внимание. Кажется, это работает только потому, что ошибка игнорируется несколько раз? Я использую LaTeX2e < 2005/12/01>. Я думаю, что часть кода в hook_plot_tex функции линии 120 крючков-latex.R:

fig2 = sprintf('\\caption%s{%s\\label{%s}}\n\\end{%s}\n', scap, cap, 
       paste(lab, if (mcap) fig.cur, sep = ''), options$fig.env) 

Это исправить?

fig2 = sprintf('\\caption%s{%s}\\label{%s}\n\\end{%s}\n', scap, cap, 
       paste(lab, if (mcap) fig.cur, sep = ''), options$fig.env) 

Предложения? Я не знаком с процессом github ... Спасибо!

ответ

8

Короткий ответ - это проблема LaTeX, вызванная слишком большим количеством команд \ includegraphics и без разрывов страниц. Функция для выполнения нескольких фигур с подписями и этикетками внутри цикла (с кредитом Стив Пауэлл и Yihui):

plot.knit<-function(chunkLabel,#text for chunk label which is also used for figure file name 
       capt,#text for caption 
       plt)#plot object to be placed 
    { 
    cat(knit(text=(paste("<<",chunkLabel,",fig.pos='h',fig.cap='",capt,"'>>=\nplt\[email protected]",sep='')))) 
} 
cat('\\newpage')#some sort of page break must be inserted along the way to keep latex from breaking. 

Это может быть изменено, чтобы добавить любого из вариантов куска вы хотели бы.

Долгосрочный ответ: Вот что я сделал, чтобы заставить его работать. Я загрузил knitr из github, сделал предложенное изменение выше, скомпилировал и провел пример. Измененный код не изменил результат. Дальнейшее исследование ошибки латексной взял меня к LaTeX FAQ, где говорится:

ошибка также возникает в длинной последовательности поплавковых сред, без промежуточного текста. Если среда не будет соответствовать «здесь» (и вы позволили им пойти «здесь»), никогда не будет перерыва страницы, и поэтому LaTeX никогда не сможет пересмотреть место размещения. (Конечно, поплавки не могут соответствовать «здесь», если последовательность достаточно длительная: после заполнения страницы LaTeX больше не будет плавать, что приведет к ошибке.

Методы разрешения могут включать переопределение поплавков с использованием флотатора [H] с плавающей точкой, но вы вряд ли уйдете, не используя \ clearpage время от времени.

Итак, я добавил

cat('\\clearpage') 

после того, как участки формируются в каждом шаге цикла. Это привело к тому, что ошибки не были выброшены, а цифры в правильных местах. Кроме того,

cat('\\newpage') 

работает и, кажется, лучше работает, разместив фигуры 2 на странице в моем фактическом документе.

Рабочий код:

\documentclass{article} 

    \begin{document} 
<<startup,echo=FALSE,results='hide',message=FALSE,tidy=FALSE,warning=FALSE,fig.keep='all',comment=NA>>= 
require(knitr) 
require(ggplot2) 
opts_knit$set(progress = F, verbose = F) 
opts_chunk$set(comment=NA, 
      tidy=FALSE, 
      warning=FALSE, 
      message=FALSE, 
      echo=FALSE, 
      dpi=600, 
      fig.width=6.75, fig.height=4, # Default figure widths 
      dev=c("pdf",'tiff'), 
      dev.args=list(pdf=list(NULL),tiff=list(compression='lzw')), 
      error=FALSE) 
@ 
<<plotloop,results='asis'>>= 
for(x in seq(1,20)){ 
    x1<-data.frame(x=seq(1,10),y=seq(1,10)) 
    plt<-ggplot(data=x1,aes(x,y))+geom_point() 
    figLabel=paste('Figure',x,sep='') 
    capt<-paste('Caption for fig.',x) 
    cat(knit(text=(paste("<<",figLabel,",fig.pos='h',fig.cap='",capt,"'>>=\nplt\[email protected]",sep='')))) 
cat('\\newpage') 
} 
@ 

\end{document} 
+1

Я думаю, что это будет чище использовать дочерние документы вместо того, чтобы динамически создавать куски кода с помощью 'пасты()'. См. Пример 20: https://github.com/yihui/knitr-examples –

+0

не может решить, как адаптировать это для файлов .Rmd: https://stackoverflow.com/questions/27443019/knitr-plots-labels- и-подпись, в-один-кусок RMD-файлы –

Смежные вопросы