1

I have the following data:

library(dplyr)
    set.seed(122)
    df <- as_tibble(rlnorm(1260, meanlog = 0.06, sdlog = 0.20))
date <- rep(c("Jan", "Feb", "Mär", "Apr", "Mai", "Jun", 
      "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"), 5)

These are supposed to be 1260 daily prices with one year = 252 days and 1 month = 21 days.

Now, I want to draw a line-chart with the daily prices on the y-axis and months on the x-axis. The code below is adapted form this thread Graphing time-series data when date column doesn't exist:

library(tidyverse)

df %>%
    as.data.frame() %>%
    rename(price = 1) %>% 
    mutate(rnames = rownames(.)) %>% 
    ggplot(aes(x = as.numeric(rnames), y = price, 
                group = rep(1:5, times=1, each=252))) +
      geom_line() +
      labs(title = "Stock Price Chart", y = "Price", x = "date") +
      scale_x_continuous(breaks = seq(1, 1260, by = 21), labels = date)

However, I slightly changed my df by inserting a new first row with value 1.

df <- rbind(df[0,],c(1),df[1:nrow(df),])

This is supposed to be the starting price at t=0. Unfortunately, the code doesn't work out now. Is there a quick fix for this?

M--
  • 25,431
  • 8
  • 61
  • 93
Jj Blevins
  • 355
  • 1
  • 13
  • I did this:`df <- rbind(df[0,],c(1),df[1:nrow(df),])` – Jj Blevins May 27 '19 at 19:19
  • we don't have `df[0,]`. This is what I get if I run your code: ```Error in df[0, ] : incorrect number of dimensions``` – M-- May 27 '19 at 19:22
  • sorry `df <- as_tibble(df)` is applied beforehand. – Jj Blevins May 27 '19 at 19:24
  • Look at my edits. You need to show all of these and make sure they are formatted correctly. Your question should be reproducible, minimal and legible (nicely formatted). Moreover, you should provide most of the information in the body of question, not the comments. That's why I added them. Read this thread about a reproducible example: https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example ... I will post an answer shortly. – M-- May 27 '19 at 19:29
  • Thank you for the help. I am going to post better examples in the future. – Jj Blevins May 27 '19 at 19:31

1 Answers1

1
library(tidyverse)

df %>%
  as.data.frame() %>%
  rename(price = 1) %>% 
  mutate(rnames = rownames(.)) %>% 
  ggplot(aes(x = as.numeric(rnames)-1, y = price, 
             group = c(1,rep(1:5, times=1, each=252)))) +
  geom_line() +
  labs(title = "Stock Price Chart", y = "Price", x = "date") +
  scale_x_continuous(breaks = seq(1, 1260, by = 21), labels = date)

You can also add a new breakpoint for point 0. by changing like scale_x like this:

scale_x_continuous(breaks = c(0, seq(1, 1260, by = 21)), labels = c("t=0", date))

If you still want the datapoint with price == 1 (your new row) be labeled as Jan then you don't need to subtract 1 from your x in the aesthetics and your breaks don't need to be manipulated. It works either way.

The most important thing to get my previous code to work with your new dataframe is changing the group in the aesthetics to be the same size as your new dataframe.

M--
  • 25,431
  • 8
  • 61
  • 93
  • I just removed the paddings to the left and right with `scale_x_continuous(breaks = seq(1, 1260, by = 21), labels = date,expand = c(0,0))`. However, now I see that the first y-value "1" starts outside the x-axis. I would like it to lie on the first x-value "Jan". Is this possible somehow? To further clarify: the first y-value should correspond to January 1st, while the last y-value should correspond to December 31st (December 21st in my expample, as months only have 21 days) – Jj Blevins May 28 '19 at 08:49
  • @JjBlevins As I outlined in my answer, just need to get rid `-1` in the `aes` of `ggplot` so that line would be ```ggplot(aes(x = as.numeric(rnames), y = price,``` ... and the rest stays as what I have at the top of my answer (full solution) and you just add your `,expand = c(0,0)` in the `scale_x` function. – M-- May 28 '19 at 14:02
  • 1
    I said it in the answer: *If you still want the datapoint with price == 1 (your new row) be labeled as Jan then you don't need to subtract 1 from your x in the aesthetics and your breaks don't need to be manipulated.* To be clear, now you have (1261 datapoints) equal to (5 years * 12 month * 21 days + 1 day). – M-- May 28 '19 at 14:05
  • thank you it worked! I asked in the following thread how to add an aditional x-axis for years: https://stackoverflow.com/questions/56339970/ggplot2-add-secondary-x-label-year-below-months Maybe you could help out there? – Jj Blevins May 28 '19 at 17:50
  • I just looked closely and even without facet grids there are these "jumps" between years. Any idea why? – Jj Blevins May 30 '19 at 21:50
  • 1
    @JjBlevins That's because of grouping. https://stackoverflow.com/questions/19731718/how-to-connect-points-of-different-groups-by-a-line-using-ggplot – M-- May 30 '19 at 21:51
  • is it preventable? – Jj Blevins May 30 '19 at 21:52
  • 1
    @JjBlevins just do not use `group` in your `aes` at all; meaning, get rid of ```group = c(1,rep(1:5, times=1, each=252))``` – M-- May 30 '19 at 21:57
  • that solved the problem, thanks. But why use it in the first place? – Jj Blevins May 30 '19 at 23:01
  • @JjBlevins I personally don't think connecting different years is a good idea unless you want to see the trends in a decade (and not annually). – M-- May 30 '19 at 23:05
  • I understand! Thank you. – Jj Blevins May 30 '19 at 23:13