Formatting numbers on axis when using ggplot2

please note: this is not a duplicate to this question. This question deals with a similar issue like here instead, which was unfortunately not answered.

It is an updated version of this question, which was - in my view - wrongly classified as duplicate.

I want to format the numbers on x-axis-ticks when the x-axis is a discrete variable. A quick example:

library(scales)

RN <- sample(1:1000,1000,replace=TRUE)
RN <- RN/1000
breaks <- c(seq(from=0, to=1, by=0.05))
DF <- data.frame(RN)
DF$DisRN <- cut(DF$RN,breaks=c(breaks,Inf),labels=as.numeric(breaks))
DF_Plot <- DF %>% group_by(DisRN) %>% summarise(cnt=n())
ggplot(DF_Plot,aes(y=cnt,x=DisRN)) + geom_bar(position="dodge",stat="identity")

What I get is this output from plot

However, what I want to get is to have numbers formatted at the x-axis to uniquely two digits after the decimal point each (ie. 0.00, 0.05, 0.10, 0.15 0.20 etc.)

Advice given here does not work, since

ggplot(DF_Plot,aes(y=cnt,x=DisRN)) + geom_bar(position="dodge",stat="identity") +
 scale_x_continuous(labels = scales::label_number(accuracy = 0.01))

ends up with an error message:

Error: Discrete value supplied to continuous scale

scale_x_discrete() does not appear to have a similar option.

Additional question: Is there a way to leave out the description of some bars?

Thanks already for any help.


Solution 1:

Exploiting the fact that you can give a (lambda) function as the labels argument, you can just reconvert the character label to numeric before passing it on to scales::number.

library(ggplot2)
library(scales)
library(dplyr)

RN <- sample(1:1000,1000,replace=TRUE)
RN <- RN/1000
breaks <- c(seq(from=0, to=1, by=0.05))
DF <- data.frame(RN)
DF$DisRN <- cut(DF$RN,breaks=c(breaks,Inf),labels=as.numeric(breaks))
DF_Plot <- DF %>% group_by(DisRN) %>% summarise(cnt=n())


ggplot(DF_Plot,aes(y=cnt,x=DisRN)) +
  geom_col(position="dodge") +
  scale_x_discrete(
    labels = ~ number(as.numeric(.x), accuracy = 0.01)
  )

Created on 2022-01-11 by the reprex package (v2.0.1)

You can leave out some breaks by setting the breaks argument of the scale to, for example, breaks = seq(0, 0.9, by = 0.1).

Solution 2:

group_by in DF_Plot <- DF %>% group_by(DisRN) %>% summarise(cnt=n()) transforms DisRN to factor. Transforming back to numeric like as.numeric(DisRN)` will resolve the issue:

ggplot(DF_Plot,aes(y=cnt,x=as.numeric(DisRN))) + geom_bar(position="dodge",stat="identity") +
  scale_x_continuous(labels = scales::number(as.numeric(.x), accuracy = 0.01))

enter image description here