Reputation: 1231
I am wanting to get more into using R markdown to perform analyses and generate output. Maybe I'm missing something simple, but I just want to be able to set the number of decimal places to show either 2 or 3 digits, depending on the output (e.g. t-statistic vs p-value).
I have previously used r options(digits=2)
, which works until the last digit you want to include is 0. I have gotten around this with the sprintf function, but having to specify for each number.
Is there a way to set a 'global' sprintf option so that for all numbers following, the same number of decimal places are shown?
Thank you,
Paul
Upvotes: 6
Views: 16623
Reputation: 129
As found in the tutorial here by Yihui, this is how I've successfully implemented it in my Rmd
file.
{r setup, include=FALSE, cache=FALSE}
options(scipen = 1, digits = 2) #set to two decimal
Upvotes: 1
Reputation: 5910
Defining a format for inline code output is feasible with a knitr
inline hook (hooks are the hidden gems of knitr
).
Example #1
With this Rmd
file, the number of decimals is controlled without using sprintf()
in all inline codes:
---
title: "Use an inline hook"
---
```{r setup, include=FALSE}
# Register an inline hook:
knitr::knit_hooks$set(inline = function(x) {
x <- sprintf("%1.2f", x)
paste(x, collapse = ", ")
})
```
Now, get 3.14 with just writing `r pi`.
Example #2
Want to change the inline output format in some part of the report?
This Rmd
file does the job:
---
title: "Use a closure and an inline hook"
---
```{r setup, include=FALSE}
# Register an inline hook
knitr::knit_hooks$set(inline = function(x) {
paste(custom_print(x), collapse = ", ")
})
# Define a function factory (from @eipi10 answer)
op <- function(d = 2) {
function(x) sprintf(paste0("%1.", d, "f"), x)
}
# Use a closure
custom_print <- op()
```
Now, get 3.14 with `r pi`...
```{r three-decimals, include=FALSE}
custom_print <- op(d = 3)
```
...and now 3.142 with `r pi`.
```{r more-decimals, include=FALSE}
custom_print <- op(d = 10)
```
Finally, get 3.1415926536 with `r pi`.
Example #3
Want to display different formats for t-statistic and p-value?
One can use S3 objects and an inline hook as in this Rmd
file:
---
title: "Use S3 methods and an inline hook"
---
```{r setup, include=FALSE}
# Register an inline hook
knitr::knit_hooks$set(inline = function(x) {
paste(custom_print(x), collapse = ", ")
})
# Define a generic
custom_print <- function(x, ...) {
UseMethod("custom_print", x)
}
# Define a method for p-values
custom_print.p.value <- function(x, ...) paste(sprintf("%1.2f", x), collapse = ", ")
# Define a method for t-statistics
custom_print.t.stat <- function(x, ...) paste(sprintf("%1.1f", x), collapse = ", ")
```
Estimate models...
```{r fake-results, include=FALSE}
t <- c(2.581, -1.897)
class(t) <- "t.stat"
p <- c(0.025, 0.745)
class(p) <- "p.value"
```
Want to show T-stats: `r t` (get 2.6, -1.9).
And p-values: `r p` (get 0.03, 0.74).
Who said knitr
is a wonderful package?
Upvotes: 8
Reputation: 93761
I don't know of a way to set a global option (though there may be one). But you can write a convenience output function to reduce the amount of typing. For example, put this function at the beginning of your document:
op = function(x, d=2) sprintf(paste0("%1.",d,"f"), x)
Then, later in your document, when you want to output numbers, you can, for example, do:
op(mtcars$mpg)
Or if you want 3 digits instead of the default 2, you can do:
op(mtcars$mpg, 3)
Upvotes: 5