0

I have below data structure "x":

# A tibble: 18 x 4
   mm         mm_fct     Legenda waarde
   <date>     <fct>      <chr>    <dbl>
 1 2020-07-01 2020-07-01 Gas      0.906
 2 2020-07-01 2020-07-01 Temp    17.3  
 3 2020-08-01 2020-08-01 Gas      0.935

This is plotted nicely by (x-axis needs factors(!)):

 ggplot(x, aes(mm_fct, waarde, fill = Legenda)) +
    geom_col(position = position_dodge2())

I like to have a date on the x-axis so add to scale_x_date() but then get an Error:

  ggplot(x, aes(mm_fct, waarde, fill = Legenda)) +
    geom_col(position = position_dodge2()) +
    scale_x_date(x$mm)

Error: Invalid input: date_trans works with objects of class Date only

What ever I enter as arguments in scale_x_date().

Please help !

tjebo
  • 21,977
  • 7
  • 58
  • 94
Lucky
  • 29
  • 3
  • related https://stackoverflow.com/questions/38839923/r-ggplot-bar-plot-with-month-on-x-axis and https://stackoverflow.com/questions/45485181/plotting-a-bar-plot-with-x-axis-defined-as-a-time-series-in-ggplot2 – tjebo Mar 28 '21 at 11:54

2 Answers2

1

Why don't you just use mm as the variable for the x-axis? In that case, you also don't need ggplot2::scale_x_date().

library(tidyverse)
library(lubridate)

x <- tibble::tribble(
    ~mm,          ~mm_fct,      ~Legenda, ~waarde,
    "2020-07-01", "2020-07-01", "Gas",    0.906,
    "2020-07-01", "2020-07-01", "Temp",   17.3,
    "2020-08-01", "2020-08-01", "Gas",    0.935
  ) %>%
  dplyr::mutate(
    mm = lubridate::as_date(mm),
    mm_fct = as.factor(mm_fct)
  )


ggplot2::ggplot(
    data = x,
    mapping = ggplot2::aes(
      x = mm,
      y = waarde,
      fill = Legenda
    )
  ) +
  ggplot2::geom_col(
    position = position_dodge2()
  )
van Nijnatten
  • 404
  • 5
  • 15
1

Edit: After the comment of tjebo, where he points out rightly so that this answer is nearly same as that from van Nijnatten. The only difference I can see is the use of as_date function vs. ymd function from lubridate. Upvotes to van Nijnatten!!! Please see my comment to tjebo's comment.

To handle a "quasi" time series you can use lubridate package with the ymd function. Then your x axis can be handled as time series. Now you can use scale_x_date().

library(tidyverse)
library(lubridate)

x <- x %>% 
  mutate(mm = ymd(mm))
         
ggplot(x, aes(mm, waarde, fill = Legenda)) +
  geom_col(position = position_dodge2())

data:

# code from van Nijnatten
x <- tibble::tribble(
  ~mm,          ~mm_fct,      ~Legenda, ~waarde,
  "2020-07-01", "2020-07-01", "Gas",    0.906,
  "2020-07-01", "2020-07-01", "Temp",   17.3,
  "2020-08-01", "2020-08-01", "Gas",    0.935
) 

enter image description here

TarJae
  • 72,363
  • 6
  • 19
  • 66
  • I might have missed sth essential here, but how is this different than this answer? https://stackoverflow.com/a/66840864/7941188 – tjebo Mar 28 '21 at 11:52
  • 1
    You are right. I just missed `library(lubridate)` at the beginning and concluded that the answer is without `lubridate`. But in van Nijnatten's answer there is lubridate in the middle of the code. The `ymd` function that parses dates with year, month, and day components could still be of help. Anyway you are right the only difference is the use of `as_date` function vs. `ymd` function from lubridate. Please see my edit. – TarJae Mar 28 '21 at 12:10
  • 2
    @tjebo, there is no difference. @TarJae, The only thing I pointed out is that one should not use a `character` object if you want to use it as a `date`. The `libridate` code is there only to replicate the data; it is not the solution. The solution is the first line of the answer and the last bit of the code. Cheers! – van Nijnatten Mar 28 '21 at 12:35
  • Thanks for the feedback @ van Nijnatten. – TarJae Mar 28 '21 at 13:01
  • Thanks a lot, that worked as answered! How can I now show values for each bar? So show 0.906 , 17.3, 0.935 on each bar. I tried geom_text() but as this uses the date as X-coordinate all values are on above each other where I want to do be on the bar. – Lucky Mar 28 '21 at 14:34
  • You can use this code: `ggplot(x, aes(x = as.factor(mm), y = waarde, fill = Legenda, label = waarde)) + geom_col(position = "dodge") + geom_text(position = position_dodge(width = 0.9), vjust = -0.5) + scale_x_discrete(labels = function(x) format(as.Date(x), "%b"))`. You should have a look here: – TarJae Mar 28 '21 at 19:06