逗号分隔和字符串截断

comma separation and string truncation

一段时间以来,我一直在使用一个很好的 SO solution 来为 knitr 报告中的数字添加逗号分隔,但是这个函数似乎有一个我以前从未遇到过的意想不到的后果:它用括号截断了一个字符串.我不太了解 类 的用法,看不出为什么这个函数会影响我的字符串。这是一个简单的例子。

1) 保持代码不变,逗号分隔有效 (2,015),但字符串被截断 (30.2 (10)。

2) 取下钩子,你会看到相反的情况:没有逗号分隔 (2015) 但字符串没问题 (30.2 (10.2))。

\documentclass{article}

\begin{document}

<<knitr, include=FALSE>>=
  library(knitr)
  nocomma <- function(x){structure(x,class="nocomma")}
  knit_hooks$set(inline = function(x) {
      if(!inherits(x,"nocomma")) return(prettyNum(x, big.mark=","))
      if(inherits(x,"nocomma")) return(x)
      return(x) # default
  })
@

<<ex>>=
x <- paste0("30.2 ", "(", "10.2", ")")
x
# [1] "30.2 (10.2)"
y <- "2015"
@

The `nocomma()` function does a nice job putting a comma in \Sexpr{y}, but \Sexpr{x} gets truncated.

\end{document}

我喜欢 hook 方法的一点是,所有需要 000 分隔的内联字符串都会得到逗号,而我不必手动使用函数在整个文档的每个实例中设置逗号。这可能不是一个很好的解决方案,我对其他人持开放态度。但它 对我来说是 一个非常实用的解决方案......直到今天,也就是说,当它破坏了我文档中的其他内容时:带有 ( 的字符串。

您似乎没有按预期使用该功能。如果你看at the answer to the question you link to,它自带两个实用函数:

comma <- function(x){structure(x,class="comma")}
nocomma <- function(x){structure(x,class="nocomma")}

函数定义略有不同:

knit_hooks$set(inline = function(x) {
      if(inherits(x,"comma")) return(prettyNum(x, big.mark=","))
      if(inherits(x,"nocomma")) return(x)
      return(x) # default
    })

具有 comma("2015")nocomma(paste0("30.2 ", "(", "10.2", ")")) 的预期用例。

您的版本已被修改为总是尝试放入逗号,除非明确使用nocomma()。你写:

The nocomma() function does a nice job putting a comma in \Sexpr{y}, but \Sexpr{x} gets truncated.

实际上,nocomma() 函数在您的示例中没有执行任何操作,因为您从未使用过它。您可以将它与---顾名思义,防止逗号一起使用---像这样:

A comma is added in \Sexpr{y} automatically, but using nocomma() adds no commas: \Sexpr{nocomma(x)}.

如果您正在寻找一种更自动化的解决方案,不需要您在 不想 修改时指定 nocomma(),您可以尝试让函数猜测得更好一点(就像我在评论中建议的那样):

knit_hooks$set(inline = function(x) {
      if(is.na(as.numeric(x))) return(x)
      if(!inherits(x,"nocomma")) return(prettyNum(x, big.mark=","))
      return(x) # default
  })

这将尝试将输入强制转换为数字。如果它没有得到 NA,那么它将尝试在其中放置一个逗号,否则它将保持不变。就个人而言,我更希望它只修改数字而不修改字符:

knit_hooks$set(inline = function(x) {
      if(!(is.numeric(x)) return(x)
      if(!inherits(x,"nocomma")) return(prettyNum(x, big.mark=","))
      return(x) # default
  })

这个版本只会尝试修改直接数字,所以 2015 会得到一个逗号; "2015"nocomma(2015) 不会得到逗号。