knitr HTML输出太大

knitr HTML输出太大,r,knitr,r-markdown,R,Knitr,R Markdown,我一直在使用rmarkdown/knitr的knittohtml功能为一些博客生成html代码。我发现它非常有用和方便,但最近在文件大小方面遇到了一些问题 当我编写一个包含使用shapefile或ggmapimages的图形的脚本时,html文件变得太大,博客主机无法理解它(我已经尝试使用blogger和wordpress)。我相信这与将shapefile/ggmap放入html表单的相对较大的data.frames/文件有关。我能做些什么来得到一个更小的html文件,让博客主机解析 作为参考,

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

当我编写一个包含使用shapefile或
ggmap
images的图形的脚本时,html文件变得太大,博客主机无法理解它(我已经尝试使用blogger和wordpress)。我相信这与将shapefile/
ggmap
放入html表单的相对较大的data.frames/文件有关。我能做些什么来得到一个更小的html文件,让博客主机解析


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

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

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

此处的更多信息:

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


1.优化现有HTML文件 可以在现有HTML文件上运行。脚本将:

  • 解码base64编码的图像
  • 运行以优化图像
  • 将优化后的图像重新编码为base64
用法:

python optimize_html.py infile.html
它将输出写入
infle optimized.html


2.使用内置的knitr钩子优化PNG图像 1.15包含一个名为
hook_optippng
的钩子,该钩子将在生成的PNG文件上运行程序,以减小文件大小

下面是一个
.Rmd
示例(取自:):


3.为任何图像优化器编写自己的knitr钩子 也很容易,所以我写了一个钩子来调用这个程序。我发现
pngquant
运行得更快,输出文件更小,看起来更好

下面是一个
.R
示例,它定义并使用了
hook\u pngquant
(取自)

#'---
#标题:“pngquant演示”
#作者:“卡米尔·斯洛维科夫斯基”
#'日期:''r Sys.date()`'
#“产出:
#'html_文档:
#“自给自足:是的
#' ---
#+设置,include=FALSE
图书馆(knitr)
#函数取自knitr/R/utils.R
所有图=功能(选项,ext=选项$fig.ext,num=选项$fig.num){
图路径(外部,选项,编号=序号(编号))
}
in_dir=函数(dir,expr){
如果(!is.null(dir)){
owd=setwd(dir);on.exit(setwd(owd))
}
wd1=getwd()
res=expr
wd2=getwd()
如果(wd1!=wd2)警告(
'您已将工作目录更改为',wd2'(可能通过setwd())',
'将恢复为',wd1'。请参阅?knitr::knit'中的注释部分
)
物件
}
is_windows=function().Platform$OS.type=='windows'
in_base_dir=函数(expr){
d=opts_knit$get('base.dir'))
if(is.character(d)&&!file_test('-d',d))dir.create(d,recursive=TRUE)
in_dir(d,expr)
}
#下面是您可以修改以使用任何图像优化器的代码。

hook_pngquant有没有一种方法可以嵌入图像而不是其他内容(如所有数据点等)?不确定这些是否可以真正分开,但那将是理想的。谢谢你在这个方向上的观点。你说的数据点是什么意思?呈现knitr/RMarkdown文档时,进入HTML的唯一内容是文档中的文本/代码,以及打印或打印的任何内容。因此,除非将数据帧显式打印到屏幕上,否则数据点本身只会间接显示在绘图中。如果您使用SVG或类似的东西,那么图像会很大,因为它们存储每个数据点,但是如果您只是使用默认值(PNG),那么这不应该是一个问题。我认为每个数据帧的内容以某种方式存储在编织的html中,就像html代码是运行计算的整个过程一样,等等。我之所以这么想,是因为html文件比word文档大得多。显然,我不太熟悉这些内部工作,也不太熟悉html,因此感谢您的帮助。@moman822 Jupyter/Ipython笔记本确实以JSON存储了一些中间数据结构,但knitr的情况并非如此。文件大小的差异可能与html/doc输出的不同默认图像格式以及嵌入到独立html输出文件中的外部javascript和CSS文件有关。通过生成HTML的非独立版本,您还可以更轻松地确定每个图像的大小,如果有一个图像特别大,您可以尝试更改图像的尺寸、格式等以减小其大小。
hook\u pngquant
自1.15.1版起在
knitr
中本机提供
# 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))
```
#' ---
#' 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))