【问题标题】:Format inline output conditional on textual context根据文本上下文格式化内联输出
【发布时间】:2016-06-10 11:41:47
【问题描述】:

使用对默认内联 knitr 挂钩的修改(改编自 Jason French 的博客文章 here),我打印的数字输出四舍五入到小数点后 3 位。如果值小于 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 = &lt; 0.001。最好是p &lt; 0.001。是否可以让knitr 检查在内联表达式之前是否有等号,如果是,请在适当的时候取消它?

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

【问题讨论】:

  • "是否可以让 knitr 检查内联表达式之前是否有等号[?]" 不,我不这么认为。没有内联钩子的解决方案(但使用起来相对简单)也可以吗?
  • @CL。 - 我曾认为我可能不得不重新定义一个函数fun,它将舍入值作为字符串返回,并在前面加上适当的=&lt;。然后在必要时调用它,例如Blah was significant (test statistic `r fun(stat)`, p `r fun(p)`),当需要没有前导 =/&lt; 的值时,不要调用 fun。你是这么想的吗?我对任何解决方案都持开放态度,但显然越简单(更易读)越好。
  • 这正是我的想法,是的。您可以将钩子用于stat 等普通数字,仅用于您将使用fun(p) 的p 值(或更有趣的命名p(p))。
  • @CL。 - 随时为后代发布一个示例,如果没有更简单的解决方案出现,我会接受(我认为你是对的......表达式无法意识到周围的文字......我可以@987654338 @, gsub = &lt; 出来,然后在编织之前再写出来,但这看起来很笨拙......)

标签: r formatting knitr sweave


【解决方案1】:

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

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

简单的解决方案

可以使用asis_output绕过钩子:

`r asis_output(0.0001)`

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

缺点:你要么使用钩子,但你不知道你是否得到[number]&lt; [number]作为输出(当你想要像“p = [number]”/“p asis_output;那么你知道不会有(不)等号,但你不能利用这个钩子。

高级解决方案

以下函数适用inline_hook,但如果钩子没有添加&lt;,则添加一个额外的=符号:

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多