【问题标题】:Dynamic height and width for knitr plotsknitr 图的动态高度和宽度
【发布时间】:2013-02-28 05:42:16
【问题描述】:

在 knitr 中,可以通过简单地在块选项中指定绘图的大小来指定它。

例如:

```{r, fig.width=9,fig.height=3}
plot(x)
```

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

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

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

【问题讨论】:

    标签: r knitr


    【解决方案1】:

    我刚刚发现了一篇很棒的博客文章。

    阅读更多at Michael J Williams' blog - 我无耻地窃取了代码,所以那里有更多细节。 记得将块选项设置为 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)
    }
    ```
    

    迈克尔在帖子中警告你必须小心:

    由于我们使用 results='asis',如果我们想从块中输出文本或标题或其他任何内容,我们必须使用原始 HTML,而不是 Markdown,我们必须使用 cat() 来执行此操作,而不是打印()。例如:

    g <- ggplot(economics, aes(date, unemploy)) + 
      geom_line()
    
    cat('<h2>A Small Square Plot</h2>')
    subchunkify(g, 3, 3)
    

    再说一遍,这不是我的工作……请前往lovely blog post 了解更多详情。希望这对你有用。

    【讨论】:

    • 我需要修改subchunkify 函数的最后一行,使其读取为cat(trimws(knitr::knit(text = knitr::knit_expand(text = sub_chunk), quiet = TRUE)))。然后一切都很好。
    【解决方案2】:

    解决此问题的一种方法,尤其是如果您想在循环中更改图形参数,

    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)
      ```
      

    【讨论】:

      【解决方案3】:

      例如,您可以在另一个块中定义宽度,然后使用它

      ```{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 查看当前块(而不是必须事先定义它)。我一直在玩“之前”的钩子,想看看我能不能从中得到一些东西。到目前为止还没有骰子。
      • @BrandonBertelsen 我明白这一点,但是knitr 必须在评估块之前打开图形设备(具有适当的大小),因此您必须评估代码前一个块,以便使用后一个块中的对象。
      • @BrandonBertelsen 我不能说比怡辉更好。对我来说,将所有参数设置在一个块中会更好的可读性,例如 init.chunck。
      猜你喜欢
      • 2018-01-13
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 2015-09-22
      • 1970-01-01
      • 2010-12-17
      • 2011-04-13
      • 2017-02-23
      相关资源
      最近更新 更多