在一个代码块中使用knitr绘图、标签和标题

11

我正在制作一份 LaTeX 报告,其中在 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\n@",sep=''))))
}
@
\end{document}

这几乎可行。问题在于knitr将闭合的\caption大括号放在\label大括号外面,可以在下面的.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}

如果只有少量这样的图形,LaTeX可以处理,但是对于更大量的绘图,它会开始将它们放置不正确。

我也尝试过用

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

采用相同的方法可以得到相同的结果。

进一步说明:我在维基百科的LaTeX/Floats...页面上找到了这个内容:(链接)

如果您想标记一个图形,以便以后可以引用它,则必须在标题后添加标签(似乎在LaTeX 2e中内部工作),但必须在浮动环境内部。 如果在外部声明,它将给出节号。

“在LaTeX 2e中内部工作”的部分引起了我的注意。这似乎只是因为忽略了错误多次才能正常工作?我正在使用LaTeX2e <2005/12/01>。我认为代码片段位于hooks-latex.R文件的hook_plot_tex函数的第120行:

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的流程... 谢谢!

1个回答

8

简单地说,这似乎是一个LaTeX问题,由于过多的\includegraphics命令和没有分页符引起的。使用循环实现多个带标题和标签的图形的函数(感谢Steve Powell和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\n@",sep=''))))
}
cat('\\newpage')#some sort of page break must be inserted along the way to keep latex from breaking.

这可以通过添加任何您想要的块选项进行修改。

长答案: 以下是我所做的事情以使其正常工作。我从github上下载了knitr,按照上述建议进行了更改,编译并运行示例。修改后的代码并没有改变结果。对LaTeX错误的进一步调查引导我到LaTeX FAQ,其中指出:

当一系列浮动环境中没有插入文本时,也会出现此错误。除非环境适合“here”(而且您允许它们去“here”),否则永远不会进行页面断开,因此永远不会有重新考虑放置的机会。(当然,如果序列足够长,则所有浮点数都无法适合“here”:一旦页面填满,LaTeX将不再放置任何浮点数,导致错误。

解决的技巧可能包括使用float程序包的[H]浮点限定符重新定义浮点数,但是您可能难以避免不时使用\clearpage。

因此,我添加了

cat('\\clearpage')

在循环的每一步生成图形后,进行这项操作。这样做可以避免出现错误,并且图形位置正确。此外,保留了HTML标签。
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\n@",sep=''))))
cat('\\newpage')
}
@

\end{document}

1
我认为使用子文档会更加清晰,而不是使用 paste() 动态创建代码块。请参考示例 20:https://github.com/yihui/knitr-examples - Yihui Xie
无法弄清如何将其适应于.Rmd文件:https://stackoverflow.com/questions/27443019/knitr-plots-labels-and-captions-within-one-chunk-rmd-files - Steve Powell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接