knitr图表的动态高度和宽度

43
在knitr中,只需在代码块选项中指定大小即可指定绘图的大小。
例如:
```{r, fig.width=9,fig.height=3}
plot(x)
```

我希望能够根据变量x动态地调整图形的高度和宽度。假设x是一个数据框:

x <- data.frame(x=factor(letters[1:3]),y=rnorm(3))

举个例子,假设我想要将 fig.height 调整为等于 length(unique(x$x))

3个回答

37

你可以在另一个块中定义宽度,然后再使用它

```{r,echo=FALSE}
x <- data.frame(x=factor(letters[1:3]),y=rnorm(3))
len = length(unique(x$x))
```


```{r fig.width=len, fig.height=6}

plot(cars)
```

我喜欢这个答案,只是希望有一种方法可以让knitr查看当前块(而不是之前定义它)。我一直在尝试使用“before”钩子,看看能否从中得到一些东西。但目前为止没有成功。 - Brandon Bertelsen
4
我明白,但是 knitr 必须在执行代码块之前打开一个图形设备(具有适当的大小),因此您必须在先前的代码块中评估代码以便在后续的代码块中使用这些对象。 - Yihui Xie
@BrandonBertelsen 我无法比Yihui说得更好。对我来说,将所有参数放在一个块中(例如init.chunck)更易于阅读。 - agstudy

18

我刚找到了一篇关于这个的好博客文章。

Michael J Williams'的博客中阅读更多内容 - 我无耻地窃取了代码,所以那里有更多细节。 记得将整块选项设置为results = "asis"。

假设你想要使用循环输出一堆图形,但是你希望它们各自具有不同的大小。请定义以下函数(再次强调,我只是复制粘贴这里的内容):

subchunkify <- function(g, fig_height=7, fig_width=5) {
  g_deparsed <- paste0(deparse(
    function() {g}
  ), collapse = '')

  sub_chunk <- paste0("
  `","``{r sub_chunk_", floor(runif(1) * 10000), ", fig.height=",
   fig_height, ", fig.width=", fig_width, ", echo=FALSE}",
  "\n(", 
    g_deparsed
    , ")()",
  "\n`","``
  ")

  cat(knitr::knit(text = knitr::knit_expand(text = sub_chunk), quiet = TRUE))
}

像这样使用函数,定义自己的图形大小:

```{r echo=FALSE, results='asis'}
g <- ggplot(economics, aes(date, unemploy)) + 
  geom_line()
subchunkify(g, 10, 3)
subchunkify(g, 7, 7)
```

或者让数据定义尺寸:

```{r echo=FALSE, results='asis'}
g <- ggplot(economics, aes(date, unemploy)) + 
  geom_line()
for (i in seq(2, 5)) {
  subchunkify(g, i / 2, i)
}
```

在这篇文章中,Michael警告说你必须小心:

因为我们使用了results='asis',所以如果我们想要从代码块中输出文本、标题或其他任何内容,我们必须使用原始HTML而不是Markdown,并且我们必须使用cat()来实现,而不是print()。例如:

g <- ggplot(economics, aes(date, unemploy)) + 
  geom_line()

cat('<h2>A Small Square Plot</h2>')
subchunkify(g, 3, 3)

再次强调,这不是我的工作......去那个美好的博客文章获取更多细节。希望这对你有用。


我需要修改subchunkify函数的最后一行,使其读取cat(trimws(knitr::knit(text = knitr::knit_expand(text = sub_chunk), quiet = TRUE)))。然后一切都很好地运作了。 - Lauren Samuels
这非常接近,但我无法忍受使用“asis”选项所需的额外更改。 - mikemtnbikes

0

解决这个问题的一个方法,尤其是如果您想在循环内部更改图形参数,则可以采用以下方法:

  1. 定义另一个代码块,一个执行循环的函数
  2. 在以下代码块中分别定义图形细节

    ```{r, echo=FALSE}
    testFunction <- function (parameter) {
        x <- data.frame(x=c(1:parameter), y=rnorm(parameter))
        g1 <- ggplot(data=x, aes(x=x, y=y)) + geom_point()
        print(g1)
    }
    ```
    
    
    ```{r fig.width=10, fig.height=6}
    testFunction(10)
    ```
    
    
    ```{r fig.width=5, fig.height=4}
    testFunction(4)
    ```
    

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