knitr HTML输出太大了

时间:2016-08-07 15:41:30

标签: r knitr r-markdown

我一直在使用rmarkdown / knitr knit to html功能为某些博客生成HTML代码。我发现它非常有用和方便,但最近因文件大小而遇到了一些问题。

当我编写一个包含使用shapefile或ggmap图像的图形的脚本时,html文件太大而博客主机无法理解它(我已经尝试过使用blogger和wordpress) 。我相信这与相对较大的data.frames /文件有关,shapefile / ggmap被放入html格式。我有什么办法可以获得一个可以被博客主机解析的小型html文件吗?

作为参考,来自rmarkdown脚本的html输出,其中一个图形使用ggmap图层,一层shapefile和一些数据是1.90MB,这对于博客或wordpress在html输入中处理来说太大了。谢谢你的任何想法。

2 个答案:

答案 0 :(得分:3)

以下是3种不同的选项,可帮助您减少带有编码图像的HTML文件的文件大小。

1。优化现有HTML文件

您可以在现有HTML文件上运行this Python script。该脚本将:

  • 解码base64编码图像
  • 运行pngquant以优化图片
  • 将优化图像重新编码为base64

用法:

python optimize_html.py infile.html

它将输出写入infile-optimized.html

2。使用内置编织钩来优化PNG图像

knitr 1.15包含一个名为hook_optipng的钩子,它将在生成的PNG文件上运行optipng程序以减小文件大小。

以下是.Rmd示例(摘自:knitr-examples/035-optipng.Rmd):

# 035-optipng.Rmd

This demo shows you how to optimize PNG images with `optipng`.

```{r setup}
library(knitr)
knit_hooks$set(optipng = hook_optipng)
```

Now we set the chunk option `optipng` to a non-`NULL` value,
e.g. `optipng=''`, to activate the hook. This string is passed to
`optipng`, so you can use `optipng='-o7'` to optimize more heavily.

```{r use-optipng, optipng=''}
library(methods)
library(ggplot2)
set.seed(123)
qplot(rnorm(1e3), rnorm(1e3))
```

3。为任何图像优化器编写自己的knitr钩子

Writing your own hook也很简单,所以我编写了一个调用pngquant程序的钩子。我发现pngquant运行得更快,输出文件更小,看起来更好。

以下是.R示例,用于定义和使用hook_pngquant(取自this gist)。

#' ---
#' title: "pngquant demo"
#' author: "Kamil Slowikowski"
#' date: "`r Sys.Date()`"
#' output:
#'   html_document:
#'     self_contained: true
#' ---

#+ setup, include=FALSE
library(knitr)

# Functions taken from knitr/R/utils.R
all_figs = function(options, ext = options$fig.ext, num = options$fig.num) {
  fig_path(ext, options, number = seq_len(num))
}
in_dir = function(dir, expr) {
  if (!is.null(dir)) {
    owd = setwd(dir); on.exit(setwd(owd))
  }
  wd1 = getwd()
  res = expr
  wd2 = getwd()
  if (wd1 != wd2) warning(
    'You changed the working directory to ', wd2, ' (probably via setwd()). ',
    'It will be restored to ', wd1, '. See the Note section in ?knitr::knit'
  )
  res
}
is_windows = function() .Platform$OS.type == 'windows'
in_base_dir = function(expr) {
  d = opts_knit$get('base.dir')
  if (is.character(d) && !file_test('-d', d)) dir.create(d, recursive = TRUE)
  in_dir(d, expr)
}

# Here is the code you can modify to use any image optimizer.
hook_pngquant <- function(before, options, envir) {
  if (before)
    return()
  ext = tolower(options$fig.ext)
  if (ext != "png") {
    warning("this hook only works with PNG")
    return()
  }
  if (!nzchar(Sys.which("pngquant"))) {
    warning("cannot find pngquant; please install and put it in PATH")
    return()
  }
  paths = all_figs(options, ext)
  in_base_dir(lapply(paths, function(x) {
    message("optimizing ", x)
    cmd = paste(
      "pngquant",
      if (is.character(options$pngquant)) options$pngquant,
      shQuote(x)
    )
    message(cmd)
    (if (is_windows())
      shell
      else system)(cmd)
    x_opt = sub("\\.png$", "-fs8.png", x)
    file.rename(x_opt, x)
  }))
  return()
}

# Enable this hook in this R script.
knit_hooks$set(
  pngquant = hook_pngquant
)

#' Here we set the chunk option `pngquant='--speed=1 --quality=0-50'`,
#' which activates the hook.

#+ use-pngquant, pngquant='--speed=1 --quality=0-50'
library(methods)
library(ggplot2)
set.seed(123)
qplot(rnorm(1e3), rnorm(1e3))

我更喜欢用R脚本(.R)而不是R降价文档(.Rmd)编写报告。有关如何执行此操作的详细信息,请参阅http://yihui.name/knitr/demo/stitch/

答案 1 :(得分:0)

您可以做的一件事是不使用嵌入式图像和其他资源。为此,您可以将文档的YAML标题中的self_contained选项设置为false,例如:

---
output:
  html_document:
    self_contained: false
---

此处有更多信息:http://rmarkdown.rstudio.com/html_document_format.html