根据文本上下文格式化内联输出

Format inline output conditional on textual context

使用对默认内联 knitr 挂钩的修改(改编自 Jason French 的博客 post here),我正在打印四舍五入到小数点后 3 位的数字输出。如果该值小于 0.001,则 returns "< 0.001".

这是一个显示钩子修改的 MWE,以及我如何在 R Markdown 中实际使用它:

```{r setup, echo=FALSE}
library(knitr)
inline_hook <- function(x) {
  if (is.numeric(x)) {
    res <- ifelse(x == round(x),
      sprintf("%d", x),
      sprintf("%.3f", x)
    )
    res <- ifelse(x < 0.001, '< 0.001', res)
    paste(res, collapse = ", ")
  } else paste(as.character(x), collapse = ", ")
}

knit_hooks$set(inline = inline_hook)
``` 

```{r, echo=FALSE}
stat <- 1.2345
p <- 0.000001
```

Blah was significant (test statistic = `r stat`, p = `r p`)

以上呈现为:

Blah was significant (test statistic = 1.234, p = < 0.001)

注意 p = < 0.001。最好是 p < 0.001。是否可以让 knitr 检查等号是否在内联表达式之前,如果有,在适当的时候取消它?

以防万一,我实际上是在编写 Sweave 文档,而不是 R Markdown。

就个人而言,我不喜欢问题/链接博客中使用的 inline_hook。像这样自动转换输出对我来说似乎有风险。当前的问题就是一个很好的例子:有时转换是有害的。

这个问题有一个简单但有点复杂的解决方案。

简单的解决方案

可以使用asis_output绕过钩子:

`r asis_output(0.0001)`

输出 1e-04,即钩子不适用。否则输出为 < 0.001

缺点:你要么使用钩子,但是你不知道你得到的是 [number] 还是 < [number] 作为输出(当你想要像 "p = [number]" 这样的输出时,这是一个问题/ "p < [number]")。或者你使用 asis_output;那么你知道不会有(不)等号,但你不能利用这个钩子。

高级解决方案

以下函数适用 inline_hook 但如果钩子不添加 < 则添加额外的 = 符号:

le <- function(x) {
  rel <- if (x >= 0.001) "=" else ""
  return(asis_output(paste(rel, inline_hook(x))))
}

这样做有以下优点:

  1. 挂钩可以用
  2. 总有一个(in-)等号。

请注意 le 未矢量化。

示例:

```{r setup, echo=FALSE}
library(knitr)
inline_hook <- function(x) {
  if (is.numeric(x)) {
    res <- ifelse(x == round(x),
                  sprintf("%d", x),
                  sprintf("%.3f", x)
    )
    res <- ifelse(x < 0.001, '< 0.001', res)
    paste(res, collapse = ", ")
  } else paste(as.character(x), collapse = ", ")
}

knit_hooks$set(inline = inline_hook)

le <- function(x) {
  rel <- if (x >= 0.001) "=" else ""
  return(asis_output(paste(rel, inline_hook(x))))
}

```

* p `r le(0.01)` (value: 0.01)
* p `r le(0.001)` (value: 0.001)
* p `r le(0.0001)` (value: 0.0001)
* p `r le(0.00001)` (value: 0.00001)

输出:

p = 0.010 (value: 0.01)
p = 0.001 (value: 0.001)
p < 0.001 (value: 0.0001)
p < 0.001 (value: 0.00001)