A Bar Chart with Chronologically Sorted X-Axis dates

Hello all:

Very straightforward question as difficult as it is for me to implement:

I have a dataframe: df.
And I have a column called 'admission_date', which are all dates in January 2023 of datatype DATE.
I want to make a bar chart counting how many times each date appears in the dataframe, BUT I want the dates to be sorted chronologically in the x axis.

How would I do this?

Thanks!

R defaults to ordering axes. If I try to generate a reproducible example that looks like what you seem to describe as your data types, it automagically chronologically sorts.

2 Likes

Consider alternatives.

# fake some data
set.seed(42)
accepts <- data.frame(
    Day = seq(as.Date("2023/1/1"), as.Date("2023/1/31"), "day"),
    Acceptances = sample(1:10,31,replace = TRUE))
accepts
#>           Day Acceptances
#> 1  2023-01-01           1
#> 2  2023-01-02           5
#> 3  2023-01-03           1
#> 4  2023-01-04           9
#> 5  2023-01-05          10
#> 6  2023-01-06           4
#> 7  2023-01-07           2
#> 8  2023-01-08          10
#> 9  2023-01-09           1
#> 10 2023-01-10           8
#> 11 2023-01-11           7
#> 12 2023-01-12           4
#> 13 2023-01-13           9
#> 14 2023-01-14           5
#> 15 2023-01-15           4
#> 16 2023-01-16          10
#> 17 2023-01-17           2
#> 18 2023-01-18           3
#> 19 2023-01-19           9
#> 20 2023-01-20           9
#> 21 2023-01-21           4
#> 22 2023-01-22           5
#> 23 2023-01-23           5
#> 24 2023-01-24           4
#> 25 2023-01-25           2
#> 26 2023-01-26           8
#> 27 2023-01-27           3
#> 28 2023-01-28          10
#> 29 2023-01-29           1
#> 30 2023-01-30          10
#> 31 2023-01-31           8

library(fpp3)
#> ── Attaching packages ──────────────────────────────────────────── fpp3 0.4.0 ──
#> ✔ tibble      3.1.8      ✔ tsibble     1.1.3 
#> ✔ dplyr       1.0.10     ✔ tsibbledata 0.4.1 
#> ✔ tidyr       1.3.0      ✔ feasts      0.3.0 
#> ✔ lubridate   1.9.1      ✔ fable       0.3.2 
#> ✔ ggplot2     3.4.0
#> ── Conflicts ───────────────────────────────────────────────── fpp3_conflicts ──
#> ✖ lubridate::date()    masks base::date()
#> ✖ dplyr::filter()      masks stats::filter()
#> ✖ tsibble::intersect() masks base::intersect()
#> ✖ tsibble::interval()  masks lubridate::interval()
#> ✖ dplyr::lag()         masks stats::lag()
#> ✖ tsibble::setdiff()   masks base::setdiff()
#> ✖ tsibble::union()     masks base::union()
library(ggplot2)
library(gt)
library(pander)

accepts |> pander()
Day Acceptances
2023-01-01 1
2023-01-02 5
2023-01-03 1
2023-01-04 9
2023-01-05 10
2023-01-06 4
2023-01-07 2
2023-01-08 10
2023-01-09 1
2023-01-10 8
2023-01-11 7
2023-01-12 4
2023-01-13 9
2023-01-14 5
2023-01-15 4
2023-01-16 10
2023-01-17 2
2023-01-18 3
2023-01-19 9
2023-01-20 9
2023-01-21 4
2023-01-22 5
2023-01-23 5
2023-01-24 4
2023-01-25 2
2023-01-26 8
2023-01-27 3
2023-01-28 10
2023-01-29 1
2023-01-30 10
2023-01-31 8
accepts |> gt()
html { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif; } #kovzhddvrm .gt_table { display: table; border-collapse: collapse; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; } #kovzhddvrm .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #kovzhddvrm .gt_caption { padding-top: 4px; padding-bottom: 4px; } #kovzhddvrm .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; } #kovzhddvrm .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 0; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; } #kovzhddvrm .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #kovzhddvrm .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #kovzhddvrm .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; } #kovzhddvrm .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; } #kovzhddvrm .gt_column_spanner_outer:first-child { padding-left: 0; } #kovzhddvrm .gt_column_spanner_outer:last-child { padding-right: 0; } #kovzhddvrm .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; } #kovzhddvrm .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; } #kovzhddvrm .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; } #kovzhddvrm .gt_from_md > :first-child { margin-top: 0; } #kovzhddvrm .gt_from_md > :last-child { margin-bottom: 0; } #kovzhddvrm .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; } #kovzhddvrm .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; } #kovzhddvrm .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; } #kovzhddvrm .gt_row_group_first td { border-top-width: 2px; } #kovzhddvrm .gt_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #kovzhddvrm .gt_first_summary_row { border-top-style: solid; border-top-color: #D3D3D3; } #kovzhddvrm .gt_first_summary_row.thick { border-top-width: 2px; } #kovzhddvrm .gt_last_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #kovzhddvrm .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #kovzhddvrm .gt_first_grand_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; } #kovzhddvrm .gt_striped { background-color: rgba(128, 128, 128, 0.05); } #kovzhddvrm .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #kovzhddvrm .gt_footnotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #kovzhddvrm .gt_footnote { margin: 0px; font-size: 90%; padding-left: 4px; padding-right: 4px; padding-left: 5px; padding-right: 5px; } #kovzhddvrm .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #kovzhddvrm .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #kovzhddvrm .gt_left { text-align: left; } #kovzhddvrm .gt_center { text-align: center; } #kovzhddvrm .gt_right { text-align: right; font-variant-numeric: tabular-nums; } #kovzhddvrm .gt_font_normal { font-weight: normal; } #kovzhddvrm .gt_font_bold { font-weight: bold; } #kovzhddvrm .gt_font_italic { font-style: italic; } #kovzhddvrm .gt_super { font-size: 65%; } #kovzhddvrm .gt_footnote_marks { font-style: italic; font-weight: normal; font-size: 75%; vertical-align: 0.4em; } #kovzhddvrm .gt_asterisk { font-size: 100%; vertical-align: 0; } #kovzhddvrm .gt_indent_1 { text-indent: 5px; } #kovzhddvrm .gt_indent_2 { text-indent: 10px; } #kovzhddvrm .gt_indent_3 { text-indent: 15px; } #kovzhddvrm .gt_indent_4 { text-indent: 20px; } #kovzhddvrm .gt_indent_5 { text-indent: 25px; }
Day Acceptances
2023-01-01 1
2023-01-02 5
2023-01-03 1
2023-01-04 9
2023-01-05 10
2023-01-06 4
2023-01-07 2
2023-01-08 10
2023-01-09 1
2023-01-10 8
2023-01-11 7
2023-01-12 4
2023-01-13 9
2023-01-14 5
2023-01-15 4
2023-01-16 10
2023-01-17 2
2023-01-18 3
2023-01-19 9
2023-01-20 9
2023-01-21 4
2023-01-22 5
2023-01-23 5
2023-01-24 4
2023-01-25 2
2023-01-26 8
2023-01-27 3
2023-01-28 10
2023-01-29 1
2023-01-30 10
2023-01-31 8
ggplot(accepts, aes(Acceptances,Day)) +
  ggtitle("YTD") +
  geom_point(size = 2) +  
  scale_x_continuous(breaks = c(2,4,6,8,10)) +
  theme_bw() +
  theme(
    panel.grid.major.x = element_blank(),
    panel.grid.minor.x = element_blank(),
    panel.grid.major.y = element_line(colour = "grey60", linetype = "dashed"))


accepts_tib <- as_tsibble(accepts)
#> Using `Day` as index variable.
autoplot(accepts_tib) +
  theme_minimal()
#> Plot variable not specified, automatically selected `.vars = Acceptances`

Created on 2023-01-29 with reprex v2.0.2

Perhaps the issue is the data? I should say that this is why the suggestion of a reproducible example is crucial because I cannot imagine a use-case where this doesn't have a solution but it also leaves the underlying problem less than completely defined.

The key to making the above work is that I have a single value for each relevant date. With something like what you are describing, I suspect it is that a preliminary step may be needed, such as

library(tidyverse)
data %>% group_by(admission_date) %>% summarise(Events = n()) %>% ungroup()

Alternatively, if the issue is that it only plots dates that exist with no white space for the dates in which no entries exist, then you could use seq.Date(from=min(admission_date), to=max(admission_date), by="days") and a join.

library(tidyverse)
Summary.Table <- data %>% group_by(admission_date) %>% summarise(Events = n()) %>% ungroup()
Complete.dates <- seq.Date(from=min(admission_date), to=max(admission_date), by="days")
Plot.Data <- left_join(Complete.dates, Summary.table, by=c("admission_date" = "admission_date"))

Thanks a ton for this! Your point made me realize that I incorrectly converted the date values from string to data, so that they all turned into nulls! However, I solved the problem and then they were arranged chronologically. But when you pointed out it should do that automatically, that's when I realized I needed to give my data a second look!

1 Like

I am sorry I did not reply more promptly! I will study all this for sure though.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.