knitr 不会在绘图中挂钩科学记数法
knitr does not hook scientific notation in plots
当使用 knitr
内联时,$\Sexpr{2.5e3}$
与 .5 \times 10^3$
的拼写错误非常好。但是我想念这样一个事实,即这不适用于绘图中的标签。我猜 knitr 认为有字符而不是数字。有办法改变吗?
正如我在评论中所讨论的那样,让这一切自动发生并不容易,但翻译你的天平并不难。 sfsmisc::eaxis()
是基本地块的一个很好的解决方案。这里有一些 ggplot
风格的解决方案:
如果您想使用本机 ?plotmath
格式:
##scale function for plotting y-axis labels
scientific_10 <- function(x) {
s <- scales::scientific_format()(x)
## substitute for exact zeros
s[s=="0e+00"] <- "0"
## regex: [+]? = "zero or one occurrences of '+'"
parse(text=gsub("e[+]?", " %*% 10^", s ))
}
或者如果你使用 LaTeX/TikZ(我在这里使用 Hmisc::latexSN()
。这是一个 3 行函数,所以如果你想避免依赖或破解它,你可以直接复制它):
scientific_latex <- function(x,scipen=-2) {
require(Hmisc)
op <- options(scipen=scipen) ## encourage use of scientific notation
on.exit(options(op)
s <- paste0("$",Hmisc::latexSN(x),"$")
}
示例:
set.seed(101)
d <- data.frame(trait=runif(1000),
time=runif(1000,0,1000))
library(ggplot2); theme_set(theme_bw())
## make plot
breaks.y<-seq(from=0, to=1000, by=200)
g0 <- ggplot(d,aes(trait,time))+
geom_point()
plotmath
风格:
g0 + scale_y_continuous(label=scientific_10,
breaks=breaks.y, limits=c(0,1000))
TikZ:
g0 + scale_y_continuous(label=scientific_latex,
breaks=breaks.y, limits=c(0,1000))
在@Ben Bolker 发表评论后,我在这里也添加了我的解决方案,也许更多的是 knitr
心情,因为将 knitr
渲染应用于轴标签只是一种 hack .特别是在 knitr
文档中,人们通常会在开头设置 digits
和 scipen
并期望它被应用到所有地方。
所以在设置块中定义函数:
inline_hook <- function (x) {
if (is.numeric(x)) {
x = knitr:::format_sci(x, "latex")
i = grep("[^0-9.,]", x)
x[i] = sprintf("\ensuremath{%s}", x[i])
if (getOption("OutDec") != ".")
x = sprintf("\text{%s}", x)
}
if (is.numeric(x)) x = round(x, getOption("digits"))
x
}
这只是 knitr::.inline.hook.tex
和 knitr:::.inline.hook
的混合,最后的 collapse
被丢弃。然后根据修改scale_y_continous
的默认行为:
scale_y_continuous <- function(...) ggplot2:::scale_y_continuous(..., labels=inline_hook)
那么从上面的例子:
set.seed(101)
d <- data.frame(trait=runif(1000),
time=runif(1000,0,1000))
library(ggplot2); theme_set(theme_bw())
## make plot
breaks.y<-seq(from=0, to=1000, by=200)
g0 <- ggplot(d,aes(trait,time))+
geom_point()
g0
我默认得到:
这正是 knitr
对给定内联数字所做的。
当使用 knitr
内联时,$\Sexpr{2.5e3}$
与 .5 \times 10^3$
的拼写错误非常好。但是我想念这样一个事实,即这不适用于绘图中的标签。我猜 knitr 认为有字符而不是数字。有办法改变吗?
正如我在评论中所讨论的那样,让这一切自动发生并不容易,但翻译你的天平并不难。 sfsmisc::eaxis()
是基本地块的一个很好的解决方案。这里有一些 ggplot
风格的解决方案:
如果您想使用本机 ?plotmath
格式:
##scale function for plotting y-axis labels
scientific_10 <- function(x) {
s <- scales::scientific_format()(x)
## substitute for exact zeros
s[s=="0e+00"] <- "0"
## regex: [+]? = "zero or one occurrences of '+'"
parse(text=gsub("e[+]?", " %*% 10^", s ))
}
或者如果你使用 LaTeX/TikZ(我在这里使用 Hmisc::latexSN()
。这是一个 3 行函数,所以如果你想避免依赖或破解它,你可以直接复制它):
scientific_latex <- function(x,scipen=-2) {
require(Hmisc)
op <- options(scipen=scipen) ## encourage use of scientific notation
on.exit(options(op)
s <- paste0("$",Hmisc::latexSN(x),"$")
}
示例:
set.seed(101)
d <- data.frame(trait=runif(1000),
time=runif(1000,0,1000))
library(ggplot2); theme_set(theme_bw())
## make plot
breaks.y<-seq(from=0, to=1000, by=200)
g0 <- ggplot(d,aes(trait,time))+
geom_point()
plotmath
风格:
g0 + scale_y_continuous(label=scientific_10,
breaks=breaks.y, limits=c(0,1000))
TikZ:
g0 + scale_y_continuous(label=scientific_latex,
breaks=breaks.y, limits=c(0,1000))
在@Ben Bolker 发表评论后,我在这里也添加了我的解决方案,也许更多的是 knitr
心情,因为将 knitr
渲染应用于轴标签只是一种 hack .特别是在 knitr
文档中,人们通常会在开头设置 digits
和 scipen
并期望它被应用到所有地方。
所以在设置块中定义函数:
inline_hook <- function (x) {
if (is.numeric(x)) {
x = knitr:::format_sci(x, "latex")
i = grep("[^0-9.,]", x)
x[i] = sprintf("\ensuremath{%s}", x[i])
if (getOption("OutDec") != ".")
x = sprintf("\text{%s}", x)
}
if (is.numeric(x)) x = round(x, getOption("digits"))
x
}
这只是 knitr::.inline.hook.tex
和 knitr:::.inline.hook
的混合,最后的 collapse
被丢弃。然后根据scale_y_continous
的默认行为:
scale_y_continuous <- function(...) ggplot2:::scale_y_continuous(..., labels=inline_hook)
那么从上面的例子:
set.seed(101)
d <- data.frame(trait=runif(1000),
time=runif(1000,0,1000))
library(ggplot2); theme_set(theme_bw())
## make plot
breaks.y<-seq(from=0, to=1000, by=200)
g0 <- ggplot(d,aes(trait,time))+
geom_point()
g0
我默认得到:
这正是 knitr
对给定内联数字所做的。