knitr hook to separate 000's, but not for years

不羁的心 提交于 2019-12-23 09:48:34

问题


I define a hook at the top of my rnw to separate '000s with commas:

knit_hooks$set(inline = function(x) {
      prettyNum(x, big.mark=",")
    })

However, there are some numbers that I don't want to format like this, such as years. Is there a better way to write the hook, or a way to override the hook when I print \Sexpr{nocomma} in the example below?

\documentclass{article}

\begin{document}

<<setup>>=
  library(knitr)
  options(scipen=999) # turn off scientific notation for numbers
  opts_chunk$set(echo=FALSE, warning=FALSE, message=FALSE)
  knit_hooks$set(inline = function(x) {
      prettyNum(x, big.mark=",")
    })
  wantcomma <- 1234*5
  nocomma <- "September 1, 2014"
@

The hook will separate \Sexpr{wantcomma} and \Sexpr{nocomma}, but I don't want to separate years.

\end{document}

Output:

The hook will separate 6,170 and September 1, 2,014, but I don’t want to separate years.


回答1:


If the only things your don't want comma-separated are strings that have years in, use:

  knit_hooks$set(inline = function(x) {
      if(is.numeric(x)){
          return(prettyNum(x, big.mark=","))
      }else{
          return(x)
       }
   })

That works for your calendar string. But suppose you want to just print a year number on its own? Well, how about using the above hook and converting to character:

What about \Sexpr{2014}?   % gets commad
What about \Sexpr{as.character(2014)}?   % not commad

or possibly (untested):

What about \Sexpr{paste(2014)}?   % not commad

which converts the scalar to character and saves a bit of typing. We're not playing code golf here though...

Alternatively a class-based method:

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

  options(scipen=999) # turn off scientific notation for numbers
  opts_chunk$set(echo=FALSE, warning=FALSE, message=FALSE)
  knit_hooks$set(inline = function(x) {
      if(inherits(x,"comma")) return(prettyNum(x, big.mark=","))
      if(inherits(x,"nocomma")) return(x)
      return(x) # default
    })
  wantcomma <- 1234*5
  nocomma1 <- "September 1, 2014"  # note name change here to not clash with function

Then just wrap your Sexpr in either comma or nocomma like:

 The hook will separate \Sexpr{comma(wantcomma)} and \Sexpr{nocomma(nocomma1)}, but I don't want to separate years.

If you want the default to commaify then change the line commented "# default" to use prettyNum. Although I'm thinking I've overcomplicated this and the comma and nocomma functions could just compute the string format themselves and then you wouldn't need a hook at all.

Without knowing exactly your cases I don't think we can write a function that infers the comma-sep scheme - for example it would have to know that "1342 cases in 2013" needs its first number commad and not its second...



来源:https://stackoverflow.com/questions/26382512/knitr-hook-to-separate-000s-but-not-for-years

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!