如何在代码块中间更改knitr选项

14

您好,我想在中途更改代码块选项而无需创建新的代码块。

运行以下代码时,我期望得到两个非常不同大小的输出结果,但出于某种原因,这似乎并不是情况。

此外,第二个图根本没有绘制...(当您将其更改为plot(2:1000)时会有,但无论如何,第二个输出与第一个输出的大小相同,都是fig.width = 7。我做错了什么?

请注意“中途更改”的重要性,因为我想在运行函数时多次更改代码块选项以获取不同大小的不同输出。

```{r}
sessionInfo()

opts_chunk$set(fig.width=3)

plot(1:1000)

opts_chunk$set(fig.width=10)

plot(1:1000)

```

会话信息的输出如下:

## R version 2.15.1 (2012-06-22)
## Platform: i386-pc-mingw32/i386 (32-bit)
## 
## locale:
## [1] LC_COLLATE=English_United Kingdom.1252 
## [2] LC_CTYPE=English_United Kingdom.1252   
## [3] LC_MONETARY=English_United Kingdom.1252
## [4] LC_NUMERIC=C                           
## [5] LC_TIME=English_United Kingdom.1252    
## 
## attached base packages:
## [1] stats     graphics  grDevices datasets  utils     methods   base     
## 
## other attached packages:
## [1] knitr_0.7
## 
## loaded via a namespace (and not attached):
## [1] digest_0.5.2   evaluate_0.4.2 formatR_0.5    parser_0.0-16 
## [5] plyr_1.7.1     Rcpp_0.9.13    stringr_0.6    tools_2.15.1  

HTML 预览


1
理论上,我可以允许您使用 fig.width=c(3, 10) 并将两个图分别保存为 3 和 10 英寸,但问题在于当我记录这些图时,每个块只能使用一个大小,因此如果记录大小和绘制大小不同,则您的图可能看起来不正确(有关详细信息,请参见图形手册)。 - Yihui Xie
https://dev59.com/bmgu5IYBdhLWcg3wAici 应该是一个很好的例子,展示了如何以可编程的方式构建代码块并将它们编织在一起;虽然可能比那个案例更复杂,但你仍然可以做到。 - Yihui Xie
2个回答

9
这对我很有用,参考了Github上Yui的提示。
\documentclass{article}

\begin{document}
<<setup,echo=FALSE>>=
opts_knit$set(progress = F, verbose = F)
opts_chunk$set(comment=NA, warning=FALSE,message=FALSE,fig.width=6, echo=F)
kexpand=function(){
  cat(knit(
  text=knit_expand(text=
                     "<<yfig-{{cap}}-,fig.cap='{{cap}}',results='markup',echo=FALSE,fig.height={{figheight}},out.height={{outheight}}>>=\n
                   .q\n
                   @"
  )
))}
@

<<results='asis'>>=
library(ggplot2)
.q=qplot(1:10);cap="first caption";figheight=9;outheight=90
kexpand()
.q=qplot(1:20);cap="second caption";figheight=12;outheight=160
kexpand()

@
\end{document}

所以,其中一个关键是将进度和详细信息设置为F,否则它们会破坏输出。然后,小函数kexpand会展开内联模板,该模板作为函数的一部分被输入为文本类型。然后,您可以将您的图表定义为.q,将标题定义为cap,并定义高度等参数。您可以适应该函数以控制其他选项。奇怪的是,.q和标题不必成为函数的参数,您只需在当前环境中设置它们,函数就会自动捕获它们。不知道这是否是良好的实践或者为什么它能够工作,但它确实可以。

由于某些原因,只有我完全按照你的示例操作才能使其正常工作。如果我使用除ggplot之外的其他绘图(如基本R、metafor森林图),它就无法正常工作。更奇怪的是,如果我将高度存储在向量中并循环创建图形,它也无法正常工作。您是否知道您的方法是否可以更改以适用于我的情况?https://dev59.com/TZjga4cB1Zd3GeqPIVBd - rumtscho

5
两个问题:当你想让两个数字都保留时,请使用


```{r fig.keep='all'}

默认情况下,只保留唯一的图形(因为您的两个图形是相同的,第二个图形被删除了; 有关详细信息,请参见knitr 图形手册)。

全局代码块选项在下一个代码块开始时生效:

```{r}
opts_chunk$set(fig.width=10)
```


```{r}
opts_chunk$set(fig.width=2)
# Our figure is 10 wide, not 2
plot(1:1000)
```

```{r}
# Our figure is 2 wide, not 10
opts_chunk$set(fig.width=10)
plot(1:1000)
```

同意 fig.keep='all' 的部分。谢谢,我很感激...但问题的主要部分并不是将代码分成单独的块...正如我所提到的,我正在运行一个单一的函数,该函数产生不同大小的输出图像,并设置整个块的 fig.width 对于某些图像来说是可以的,但对于其他图像来说太小或太大了,因此我想编辑代码,在函数中的绘图之间放置 opts_current$set(fig.width=x) - h.l.m
@h.l.m 简短的回答是不行,无法以那种方式使用 opts_current - Yihui Xie
@Yihui,是否有可能更改代码块选项中的某些设置?或者这种限制会一直存在吗?我们是否可以请求将其作为未来的改进功能呢? - h.l.m
@h.l.m,我最多只能支持fig.width=a_numeric_vector,但这不是一个理想的解决方案;它可以给你正确的输出大小,但不是原始记录的大小;图形可能会看起来很丑陋。如果这是可以接受的,那么可以在Github上提出问题。 - Yihui Xie

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