0

I am trying to master plotting skills in R and for the purpose I am using the following code to generate various time series plots all at once.

pl <- as.character()
for (k in (2:ncol(db))){
    h <- paste0("ts.plot(cbind(db[,1], y = db[,",k,"]), type = 'b', 
            gpars = list(col = c('black', 'red')), 
        main = 'copper & ",colnames(db[,k]),"');")      
    pl <- paste0(pl, h)
}
eval(parse(text=substr(pl, 1, (nchar(pl)-1))))

The code works fine, however I do not manage to understand something:

  • here I am always trying to plot the series in db[,1] against all the others. How can I plot them into two separate plots one above another using ts.plot?

  • how can I change the aestetics from points to lines?

I know a better graphical set can be achieved with ggplot2. However, using the same idea with ggplot2 failed to generate the graphs, either none of them or only the last one (check also what I previously posted here, if you have a better solution please feel free to share: Why is R function parse substituting semicolons with commas?)

In any case, I would be very happy if someone could help with with the two above.

Please, use this db to reproduce my example (any time series would work)

library(stats)
set.seed(1)
x <- stats::rnorm(n = 100, mean = 0, sd = 1)
y<- stats::rnorm(n = 100, mean = 1, sd = 1)
z <- stats::rnorm(n = 100, mean = 2, sd = 1)
u <- stats::rnorm(n = 100, mean = 3, sd = 1)
db <- cbind(x,y,z,u)
Vitomir
  • 295
  • 2
  • 14
  • Can you provide a reproducible example of the data you are trying to plot ? See: https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – dc37 Dec 09 '19 at 17:13
  • Interesting question. But to help, we would be very happy if you provide a [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example/5965451). Maybe too can you sketch out your desired result maybe with image software if you cannot render it yourself? – Parfait Dec 09 '19 at 17:13
  • Thanks @dc37, Parfait, I edited adding some data for db. Indeed I am working on some random time series, so any matrix of floats works fine – Vitomir Dec 09 '19 at 18:43

1 Answers1

1

Quick question: Does the use of parse and eval is mandatory ? In my answer, I'm not using it to simplify the code. You will have to put it back if you need but it should be quite easy.

Regarding your second questions, to have lines instead of points, you need to change type="b" in type = "l".

Then, if I understand right, you are willing to plot each time series individually, right ? So, having one time serie per plot ?

For doing that, you can use par(mfrow to cut your plotting areas in multiple pieces. As ts.plot required two times series to be plot, you can cheat using the first color as white to not have db[,1] plotted on each plot:

par(mfrow = c(ncol(db),1))
for(i in 1:ncol(db))
{
  ts.plot(cbind(db[,1], y = db[,i]), type= "l", gpars = list(col = c("white","red")), main = paste0("Copper & ",colnames(db)[i]))
}

enter image description here

If you need to have db[,1] plotted on each of them, you can just do that:

par(mfrow = c(ncol(db)-1,1))
for(i in 2:ncol(db))
{
  ts.plot(cbind(db[,1], y = db[,i]), type= "l", gpars = list(col = c("black","red")), main = paste0("Copper & ",colnames(db)[i]))
}

And you get:

enter image description here

Use of ggplot2

Now, to get the same plot in ggplot2, you have to reshape your dataframe in order to get it compatible with ggplot grammar. You can achieve it using tidyverse library:

library(tidyverse)
data.frame(db) %>% 
  mutate(Time = seq(1:100)) %>%
  pivot_longer(., -Time,names_to = "Variable", values_to = "Value") 

# A tibble: 400 x 3
    Time Variable   Value
   <int> <fct>      <dbl>
 1     1 x        -0.626 
 2     1 y         0.380 
 3     1 z         2.41  
 4     1 u         3.89  
 5     2 x         0.184 
 6     2 y         1.04  
 7     2 z         3.69  
 8     2 u         1.95  
 9     3 x        -0.836 
10     3 y         0.0891
# … with 390 more rows

So, now our dataset is ready to be plotted using this code:

data.frame(db) %>% 
  mutate(Time = seq(1:100)) %>%
  pivot_longer(., -Time,names_to = "Variable", values_to = "Value") %>%
  mutate(Variable = factor(Variable, levels = c("x","y","z","u")))%>%
  ggplot(., aes(x = Time, y = Value, color = Variable)) +
  geom_line() +
  facet_grid(rows = vars(Variable))
  facet_wrap(Variable~.)

To get: enter image description here

Does it answer your question ?

dc37
  • 15,840
  • 4
  • 15
  • 32