Prevost
Prevost

Reputation: 697

Fixing rounded R values in xtable in knitr

Has anyone come up with a solution to adjust rounded R values shown in a knitr document, either as stand along \Sexpr{} or through xtable? Typing?round returns Note that for rounding off a 5, the IEC 60559 standard is expected to be used, ‘go to the even digit’.

My problem is the following scenario when showing calculated numbers from a dataframe using xtable. If the values were each shown in a separate column in a table, the reader would assume there is a calculation error:

2.5 + 3.1 = 5.6

would show up as

2 + 3 = 6

when R rounds the numbers (I have set the significant digits to 0 since the audience doesn't need more detail). This situation could potentially happen no matter how many decimal places are shown (and I would like to avoid showing any!).

I use the following for inline expressions, however I rarely insert a number into the paragraph and it usually isn't shown as a calculation. This will show 1 decimal place for numbers less than 10 and greater than -10 and should round up on even numbers ending with 0.5.

number_hook <- function(x) {
  if (is.numeric(x)) {
    if (x < 10 & x > 0 | x < 0 & x > -10) {
      y = prettyNum(x, 
                    small.mark = ".", 
                    digits = 2)
      return(y)

    } else if (sign(x) == 1) {
      y = x + 0.5
      y = trunc(y)
      y = prettyNum(y, big.mark = ",", small.mark = ".", digits = 0)
      return(y)

    } else if (sign(x) == -1) {
      y = x - 0.5
      y = trunc(y)
      y = prettyNum(y, big.mark = ",", small.mark = ".", digits = 0)
      return(y)
    }

  } else {
    x
  }
}

Any help, work-arounds, or suggestions are appreciated! Thank you!

I have also visited this similar question.

Upvotes: 0

Views: 385

Answers (1)

detroyejr
detroyejr

Reputation: 1154

My original recommendation did not work correctly. First you should modify your original function.

number_hook <- function(x) {
  ifelse(abs(x) < 10 & abs(x) > 0, prettyNum(x, small.mark = ",", digits = 2), trunc(x))
}

This should simplify the number of if statements. Then you can use:

xtable::xtable(dplyr::mutate_if(iris, is.numeric, number_hook))

To apply the function to every numeric column in your data frame.

Try it on:

foo <- data.frame(a = rnorm(10), b = rnorm(10, 10), c = rnorm(10, -10))
xtable::xtable(dplyr::mutate_if(foo, is.numeric, number_hook))

And you should get values that you need.

Upvotes: 1

Related Questions