0
votes

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.

1
Could you elaborate on how you're trying to use xtable with this? Could you not apply something like "number_hook" before creating an xtable object?detroyejr
@jonathande4 I was originally thinking about running each dataframe through a function that would round the numbers and then put that dataframe into xtable...Prevost
Assuming your original function is working as intended, could you use something like: xtable::xtable(dplyr::mutate_if(iris, is.numeric, number_hook)) xtable also has a digit parameter that you might be able to use. Does that get you what you need?detroyejr
@jonathande4 I used the function on a dataframe to create the desired latex table output. However, the function does not work correctly on the dataframe columns...I believe it is because the dataframe columns have multiple rows and arguments that are passed to the function but the function is only designed to handle a single value?Prevost
The modified function can take a character vector with a length greater than 1 and dplyr's mutate_if is designed to modify multiple rows given a logical test like is.numeric, so that should not be the problem. Are you getting an error message?detroyejr

1 Answers

1
votes

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.