Search code examples
rplotgraphplotlylubridate

Plot in R with the percentage change beetwen 2022 and 2023


I have a dataset with the column Date and a column Price, I would like a graph that shows the percentage change beetwen the months.


Date         Price
30/10/2022   129,60 € 
31/10/2022   106,10 € 
01/11/2022   87,40 € 
02/11/2022   103,80 € 
01/12/2022   60,00 € 
02/12/2022   380,50 € 
01/10/2023   243,40 € 
02/10/2023   76,00 € 
08/11/2023   318,30 € 
09/12/2023   156,30 € 
10/12/2023   49,00 € 

this is what I have done:

# Estrazione del mese e dell'anno
df$Month<- format(df$Data, "%m")
df$Year <- format(df$Data, "%Y")

# Calcolo del totale del prezzo per ciascun mese
total<- aggregate(Price ~ Month + Year, df, sum)

# Creazione del grafico a istogramma
plot <- plot_ly(totali_mese, x = ~Month, y = ~Price, color = ~Year, type = "bar") %>%
  layout(
    barmode = "group",
    xaxis = list(title = "Month"),
    yaxis = list(title = "Price"),
    legend = list(title = "Year"),
      x = totali_mese$Mese[2:nrow(totale)],
      y = totali_mese$Prezzo[2:nrow(totale)] + 20
    )

# 
plot

these codes show of course the graph that I wanted, but now I'd like a little legend above each colmun that show the change %

(I'd used this formula: '((monthvalue2023-monthvalue2022)/montvalue2022)*100').

so for october I'd have '((319,4 - 235,7)/235,7)*100' which is 61,7%

this is the graph (the values are different 'cause I used a different dataset) enter image description here


Solution

  • With just 2 years I'd go with wide format, column per year. Makes change calculation easier to follow and when adding 2 traces to Plotly, we can just add text labels to one of those:

    library(plotly)
    library(dplyr)
    library(tidyr)
    library(lubridate)
    
    df_wide <- df_ %>% 
      group_by(Year = year(Date), Month = month(Date)) %>% 
      summarise(Total = sum(Price), .groups = "drop") %>% 
      pivot_wider(names_from = Year, values_from = Total) %>% 
      mutate(Change_pct = ((`2023` - `2022`) / `2022`) %>% scales::label_percent()())
    df_wide
    #> # A tibble: 3 × 4
    #>   Month `2022` `2023` Change_pct
    #>   <dbl>  <dbl>  <dbl> <chr>     
    #> 1    10   236.   319. 36%       
    #> 2    11   191.   318. 66%       
    #> 3    12   440.   205. -53%
    
    plot_ly(df_wide, x = ~ Month) %>% 
      add_bars(y = ~ `2022`, name = "2022") %>% 
      add_bars(y = ~ `2023`, name = "2023", text = ~ Change_pct , textposition = "outside") %>% 
      layout(yaxis = list(title = "Price"))
    

    Sample data:

    df_ <- structure(list(Date = structure(c(19295, 19296, 19297, 19298, 
    19327, 19328, 19631, 19632, 19669, 19700, 19701), class = "Date"), 
        Price = c(129.6, 106.1, 87.4, 103.8, 60, 380.5, 243.4, 76, 
        318.3, 156.3, 49)), row.names = c(NA, -11L), class = c("tbl_df", 
    "tbl", "data.frame"))
    

    Created on 2023-05-25 with reprex v2.0.2