Formatting Decimal Places in R

Formatting Decimal places in R

Background: Some answers suggested on this page (e.g., signif, options(digits=...)) do not guarantee that a certain number of decimals are displayed for an arbitrary number. I presume this is a design feature in R whereby good scientific practice involves showing a certain number of digits based on principles of "significant figures". However, in many domains (e.g., APA style, business reports) formatting requirements dictate that a certain number of decimal places are displayed. This is often done for consistency and standardisation purposes rather than being concerned with significant figures.

Solution:

The following code shows exactly two decimal places for the number x.

format(round(x, 2), nsmall = 2)

For example:

format(round(1.20, 2), nsmall = 2)
# [1] "1.20"
format(round(1, 2), nsmall = 2)
# [1] "1.00"
format(round(1.1234, 2), nsmall = 2)
# [1] "1.12"

A more general function is as follows where x is the number and k is the number of decimals to show. trimws removes any leading white space which can be useful if you have a vector of numbers.

specify_decimal <- function(x, k) trimws(format(round(x, k), nsmall=k))

E.g.,

specify_decimal(1234, 5)
# [1] "1234.00000"
specify_decimal(0.1234, 5)
# [1] "0.12340"

Discussion of alternatives:

The formatC answers and sprintf answers work fairly well. But they will show negative zeros in some cases which may be unwanted. I.e.,

formatC(c(-0.001), digits = 2, format = "f")
# [1] "-0.00"
sprintf(-0.001, fmt = '%#.2f')
# [1] "-0.00"

One possible workaround to this is as follows:

formatC(as.numeric(as.character(round(-.001, 2))), digits = 2, format = "f")
# [1] "0.00"

Limit decimal places in variable in R

You can use round() option or digit.
The following code shows exactly two decimal places for the number using round()

format(round(x, 2), nsmall = 2)

For example:

> format(round(1.20, 2), nsmall = 2) [1] "1.20"
> format(round(1, 2), nsmall = 2) [1] "1.00"
> format(round(1.1234, 2), nsmall = 2) [1] "1.12"

You can format a number, say x, up to decimal places as your wish. Here x is a number with big decimal places , you can format decimal places as your wish. Such that we wish to take up to 8 decimal places of this number.

x<-c(1111111234.6547389758965789345) 
y<-formatC(x,digits=8,format="f")

[1] "1111111234.65473890"

Formatting decimal places with R

this can be achieved by combining format with sub

> x <- c(1.8, 1.55, 1.5, 1, 1.23445, 100, -1)
# the pattern (?<=\\.\\d)0$ checks if the last number after . is a zero if so replace with nothing
> sub("(?<=\\.\\d)0$", "", format(x, digits=3), perl=T )
[1] " 1.8" " 1.55" " 1.5" " 1.0" " 1.23" "100.0" " -1.0"
> sub("(^ *)(?=\\d)", "\\1+", sub("(?<=\\.\\d)0$", "", format(x, digits=3), perl=T ), perl=T)
[1] " +1.8" " +1.55" " +1.5" " +1.0" " +1.23" "+100.0" " -1.0"

Force R to always round up to two decimal places

If your numbers are in a numeric vector :

format(round(a,digits=2),nsmall=2)

which gives a character vector. The format function is there so that 1 is displayed as 1.00 and not 1 for example. If you don't care about that, omit it.


If you want 2.3421 to be rounded to 2.35 (not standard rounding but ceiling at 2 decimals), use

format(ceiling(a*100)/100,nsmall=2)

or more legible with pipes:

a %>% multiply_by(100) %>% ceiling %>% divide_by(100) %>% format(2)

Without format: ceiling(a*100)/100 which gives you a numeric.

Formatting decimal places in a character column. as.numeric erase the values in the column

I assume you are somewhere which uses a comma for a decimal point, and perhaps a decimal point in place of a thousands separator.

As an example:

df <- c(',958229561278528615818098193915712388824', '2,05561009284393218251509777394193942492', '2,72096803821411321343605598060792704404', '2,00324997757400185789440370684992098409')

First, remove any decimal points, because they may be thousands separators. Then, replace the comma with a decimal point:

as.numeric(gsub(',', '.', gsub('\\.', '', df)))

Edit: however, if you intend to use more than the first few decimal places, you may run into problems with precision. Look into the package Rmpfr if you need arbitrary precision.

How to format a number as a percentage and limit number of decimal places

You could use scales::percent()

smbsummary2<- smbsummary2%>%
group_by(area,smb)%>%
mutate(empprevyear=lag(employment),
empprevyearpp=employment-empprevyear,
empprevyearpct=((employment/empprevyear)-1), empprevyearpct=scales::percent(empprevyearpct)
)

Output:

    area period smb   employment worksites empprevyear empprevyearpp empprevyearpct
<dbl> <chr> <chr> <dbl> <int> <dbl> <dbl> <chr>
1 1 2020q1 1 46 2 NA NA NA
2 1 2020q1 2 301 4 NA NA NA
3 1 2020q1 3 466 5 NA NA NA
4 1 2020q1 4 726 6 NA NA NA
5 1 2020q1 NA 1326 7 NA NA NA
6 1 2020q2 1 48 2 46 2 4%
7 1 2020q2 2 307 4 301 6 2%
8 1 2020q2 3 474 5 466 8 2%
9 1 2020q2 4 739 6 726 13 2%
10 1 2020q2 NA 1340 7 1326 14 1%
11 3 2020q1 1 166 3 NA NA NA
12 3 2020q1 2 397 5 NA NA NA
13 3 2020q1 3 567 6 NA NA NA
14 3 2020q1 4 872 7 NA NA NA
15 3 2020q2 1 66 1 166 -100 -60%
16 3 2020q2 2 301 3 397 -96 -24%
17 3 2020q2 3 473 4 567 -94 -17%
18 3 2020q2 4 783 5 872 -89 -10%
19 3 2020q2 NA 1990 7 NA NA NA

Adjust number of decimal places in a dataset

Test %>%
mutate(sum = rowSums(across(3:last_col()), na.rm = TRUE),
across(where(is.numeric), ~sprintf("US $%.2f", .x)))

date2 Category coef1 coef2 sum
1 2021-06-30 FDE US $445.23 US $8.32 US $453.56
2 2021-06-30 ABC US $1.31 US $3.34 US $4.66
3 2021-07-01 FDE US $6.32 US $1.32 US $7.65
4 2021-07-02 ABC US $1.23 US $6.32 US $7.56


Related Topics



Leave a reply



Submit