Seasonal plot of daily data

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Seasonal plot of daily data

SNV Krishna
Hi All,

I have daily closing prices of a particular commodity. I would like to generate annual plot of the series so as to get a visual feel of the seasonality across years.

For ex I have crude oil daily price data since 2002. I would like to have multiple lines on a single plot, each line represents each year and plotted against day of year on x-axis. I tried reading the data as zoo or xts objects, but unable to plot multiple series on a single plot. Can any one help me out in this regard?

Thanks in advance for the help, rgds

SNVK
_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Re: Seasonal plot of daily data

Gabor Grothendieck
On Mon, Aug 2, 2010 at 11:28 AM, SNV Krishna <[hidden email]> wrote:
> Hi All,
>
> I have daily closing prices of a particular commodity. I would like to generate annual plot of the series so as to get a visual feel of the seasonality across years.
>
> For ex I have crude oil daily price data since 2002. I would like to have multiple lines on a single plot, each line represents each year and plotted against day of year on x-axis. I tried reading the data as zoo or xts objects, but unable to plot multiple series on a single plot. Can any one help me out in this regard?
>
> Thanks in advance for the help, rgds
>

Try this:

library(zoo)

# input data
DF <- data.frame(date = as.Date(0:999), value = 1:1000)

# create columns for year and
# julian day (1st, 2nd, ... day of the year)

DF$year <- cut(DF$date, "year")
DF$jul <- ave(DF$value, DF$year, FUN = seq_along)

# split into 1 col per year. year is col 2. index is col 3.
z <- read.zoo(DF[-1], index = 3, split = 2)

# plot - screen = 1 causes all columns to be in same frame
colors <- 1:ncol(z)
plot(z, screen = 1, col = colors)
legend("bottomright", leg = substr(levels(DF$year), 1, 4), fill = colors)

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Re: Seasonal plot of daily data

Paul Teetor
Thanks for your posting, Gabor. I liked your creative use of zoo-related
functions, and I learned something from your example.

The example wouldn't run on my machine, unfortunately, so I made some changes.
If other people have difficulties, too, perhaps my version will work for them.
(I also made some cosmetic changes.) Here it is:

library(zoo)

# Create synthetic data
DF <- data.frame(date = as.Date(0:999), value = cumsum(rnorm(1000)))

# Create columns for year and
# julian day-of-the-year (1st, 2nd, ..., Nth day of the year)
DF$year <- cut(DF$date, "year")
DF$jul <- ave(DF$value, factor(DF$year), FUN = seq)

# Create a list of vectors: each vector contains the values for one year
f <- factor(DF$year)
values <- split(DF$value, f)

# Create a list of vector: each vector contains the julian days for one year
julians <- split(DF$jul, f)

# Combine each pair of vectors (values and days), creating zoo objects
zz <- lapply(seq_along(values), function(i) zoo(values[[i]], julians[[i]]))
z <- do.call(merge.zoo, zz)
colnames(z) <- substr(levels(f),1,4)

# Plot the zoo objects:
#    Use plot.type="single" to have all columns in the same frame
#    Use plot.type="multiple" to get separate plots
colors <- 1:ncol(z)
plot(z, screens=1, col = colors, plot.type="single")
legend("bottomright", leg = substr(levels(f), 1, 4), fill = colors)


Paul Teetor, Elgin, IL  USA
http://quanttrader.info/public




________________________________
From: Gabor Grothendieck <[hidden email]>
To: SNV Krishna <[hidden email]>
Cc: "[hidden email]" <[hidden email]>
Sent: Mon, August 2, 2010 11:31:43 AM
Subject: Re: [R-SIG-Finance] Seasonal plot of daily data

On Mon, Aug 2, 2010 at 11:28 AM, SNV Krishna <[hidden email]> wrote:

> Hi All,
>
> I have daily closing prices of a particular commodity. I would like to generate
>annual plot of the series so as to get a visual feel of the seasonality across
>years.
>
> For ex I have crude oil daily price data since 2002. I would like to have
>multiple lines on a single plot, each line represents each year and plotted
>against day of year on x-axis. I tried reading the data as zoo or xts objects,
>but unable to plot multiple series on a single plot. Can any one help me out in
>this regard?
>
> Thanks in advance for the help, rgds
>

Try this:

library(zoo)

# input data
DF <- data.frame(date = as.Date(0:999), value = 1:1000)

# create columns for year and
# julian day (1st, 2nd, ... day of the year)

DF$year <- cut(DF$date, "year")
DF$jul <- ave(DF$value, DF$year, FUN = seq_along)

# split into 1 col per year. year is col 2. index is col 3.
z <- read.zoo(DF[-1], index = 3, split = 2)

# plot - screen = 1 causes all columns to be in same frame
colors <- 1:ncol(z)
plot(z, screen = 1, col = colors)
legend("bottomright", leg = substr(levels(DF$year), 1, 4), fill = colors)

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should
go.

        [[alternative HTML version deleted]]

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Re: Seasonal plot of daily data

Gabor Grothendieck
On Mon, Aug 2, 2010 at 10:39 PM, Paul Teetor <[hidden email]> wrote:
> Thanks for your posting, Gabor. I liked your creative use of zoo-related
> functions, and I learned something from your example.
>
> The example wouldn't run on my machine, unfortunately, so I made some
> changes. If other people have difficulties, too, perhaps my version will
> work for them. (I also made some cosmetic changes.) Here it is:

Since the part you replaced was the read.zoo(..., split=...) I think
its likely you are just using an old version of zoo as that feature
was added in recent versions of zoo.  Please upgrade to the latest
version of zoo on CRAN and then the code I posted should work.

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Re: Seasonal plot of daily data

SNV Krishna-2
In reply to this post by Gabor Grothendieck
Hi Gabor,

many thanks for the solution and it worked.

I tried a lot in getting appropriate function to extract year or month from
the date, but could not. Your suggestion of using cut() is great, and I have
not come across this function. Later I saw on help file, but its usage to
extract year from date was not mentioned. By the way can you mention any
other function that are useful in extracting year or month or week number or
day?

also can you tell what is 'seq_along'?

thanks and best wishes  

SNVK


-----Original Message-----
From: [hidden email]
[mailto:[hidden email]] On Behalf Of Gabor
Grothendieck
Sent: Tuesday, August 03, 2010 12:32 AM
To: SNV Krishna
Cc: [hidden email]
Subject: Re: [R-SIG-Finance] Seasonal plot of daily data

On Mon, Aug 2, 2010 at 11:28 AM, SNV Krishna <[hidden email]> wrote:
> Hi All,
>
> I have daily closing prices of a particular commodity. I would like to
generate annual plot of the series so as to get a visual feel of the
seasonality across years.
>
> For ex I have crude oil daily price data since 2002. I would like to have
multiple lines on a single plot, each line represents each year and plotted
against day of year on x-axis. I tried reading the data as zoo or xts
objects, but unable to plot multiple series on a single plot. Can any one
help me out in this regard?
>
> Thanks in advance for the help, rgds
>

Try this:

library(zoo)

# input data
DF <- data.frame(date = as.Date(0:999), value = 1:1000)

# create columns for year and
# julian day (1st, 2nd, ... day of the year)

DF$year <- cut(DF$date, "year")
DF$jul <- ave(DF$value, DF$year, FUN = seq_along)

# split into 1 col per year. year is col 2. index is col 3.
z <- read.zoo(DF[-1], index = 3, split = 2)

# plot - screen = 1 causes all columns to be in same frame colors <-
1:ncol(z) plot(z, screen = 1, col = colors) legend("bottomright", leg =
substr(levels(DF$year), 1, 4), fill = colors)

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions
should go.

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Re: Seasonal plot of daily data

Arun.stat
In reply to this post by SNV Krishna
Reply on the posting at
http://r.789695.n4.nabble.com/Seasonal-plot-of-daily-data-td2310429.html#a2310429

In case understanding seasonality is the prime concern then I would
not suggest to work with data on daily frequency. In daily data you
would find so much noise, hardly any inference can be drawn on.
Therefore some sort of working to reduce the noise may be somewhat
better idea to work with. One possible alternative could be work with
Monthly average. If some month is fundamentally strong then one should
expect it's average would be higher as compared to the other months.

Anyway following UDF might be helpful to you. Which creates monthly
average (other kind of statistic can be easily calculated after little
tweaking this code) from daily data and plots
accordingly...........Please note that, you would need to have 2
libraries viz. "zoo" & "ggplot2" pre-installed.

seasonalityPlot =
function(dat = dat, start.mo = 1) {
      library(zoo)
      library(ggplot2)
      mm = as.yearmon(index(dat)); dat = aggregate(dat, by = mm, FUN = "mean")
      mo.start.include = as.numeric(format(index(dat)[1], "%m")) - start.mo +
                         ifelse(as.numeric(format(index(dat)[1],
"%m")) - start.mo > 0 |
                                as.numeric(format(index(dat)[1],
"%m")) - start.mo == 0, 0, 12)
      end.mo = ifelse(start.mo == 1, 12, start.mo-1)
      data.end = as.numeric(format(index(dat)[length(index(dat))], "%m"))
      mo.end.include = ifelse(end.mo > data.end | end.mo > data.end,
end.mo - data.end, 12 - abs(end.mo - data.end))
      data1 = zooreg(c(rep(NA, mo.start.include), coredata(dat),
rep(NA, mo.end.include)),
                       as.yearmon(paste(ifelse(start.mo ==
as.numeric(format(index(dat)[1], "%m")) | start.mo <
as.numeric(format(index(dat)[1], "%m")),
as.numeric(format(index(dat)[1], "%Y")),
as.numeric(format(index(dat)[1], "%Y"))-1),
                                  ifelse(start.mo < 10,
paste("0",start.mo,sep=""), as.character(start.mo)), "01", sep="-")),
                       frequency=12 )
      df1 = data.frame(QUOTE = coredata(data1),
                        MONTH = format(index(data1)[1:12], "%b"),
                        YEAR =  paste("Year",
rep(1:(length(data1)%/%12), each=12), sep="-"))
      df1$MONTH = suppressWarnings(relevel(df1[,2], as.vector(df1[,2][1:12])))
      df1$YEAR = suppressWarnings(relevel(df1[,3], unique(as.vector(df1[,3]))))
      p = ggplot(df1) + geom_line(aes(y=QUOTE, x=MONTH, group=YEAR,
colour=YEAR), size=1.2)
      return(list(dat=df1, p=p)) }

You just need to copy-paste entire code and need to put some daily TS
as "zoo" object. Here is an example

library(quantmod)   # required to download data from net
dat = as.zoo(get(getSymbols("^NSEI")))[,4]
plot(dat)
seasonalityPlot(dat, 1)

Please note that, here you would have additional option (2nd argument)
to select the base month, which is by default kept as January (jan =
1).

I would also like to know from peers how above function can be
improved further...................
_____________________________________________________

Arun Kumar Saha, FRM
QUANTITATIVE RISK AND HEDGE CONSULTING SPECIALIST
Visit me at : http://in.linkedin.com/in/ArunFRM

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Re: Seasonal plot of daily data

Jeffrey Ryan
Not as pretty as ggplot of course, but for those looking for a simple
solution using base graphics:

par(mar=c(3,3,3,3))

dat_by_yr <- lapply(split.xts(apply.monthly(dat,mean),'years'),coredata)

# set up the plot window
plot.new()
plot.window(c(1,12), c(2800,6000))

# add axis and grid lines
axis(2)
axis(1,at=1:12,label=month.abb)
grid()

for(i in 1:4) lines(dat_by_yr[[i]], col=i, lwd=3)

The real value to this post comes from apply.monthly and split.xts.

HTH
Jeff

On Tue, Aug 3, 2010 at 1:50 PM, Arun Kumar Saha
<[hidden email]> wrote:

> Reply on the posting at
> http://r.789695.n4.nabble.com/Seasonal-plot-of-daily-data-td2310429.html#a2310429
>
> In case understanding seasonality is the prime concern then I would
> not suggest to work with data on daily frequency. In daily data you
> would find so much noise, hardly any inference can be drawn on.
> Therefore some sort of working to reduce the noise may be somewhat
> better idea to work with. One possible alternative could be work with
> Monthly average. If some month is fundamentally strong then one should
> expect it's average would be higher as compared to the other months.
>
> Anyway following UDF might be helpful to you. Which creates monthly
> average (other kind of statistic can be easily calculated after little
> tweaking this code) from daily data and plots
> accordingly...........Please note that, you would need to have 2
> libraries viz. "zoo" & "ggplot2" pre-installed.
>
> seasonalityPlot =
> function(dat = dat, start.mo = 1) {
>      library(zoo)
>      library(ggplot2)
>      mm = as.yearmon(index(dat)); dat = aggregate(dat, by = mm, FUN = "mean")
>      mo.start.include = as.numeric(format(index(dat)[1], "%m")) - start.mo +
>                         ifelse(as.numeric(format(index(dat)[1],
> "%m")) - start.mo > 0 |
>                                as.numeric(format(index(dat)[1],
> "%m")) - start.mo == 0, 0, 12)
>      end.mo = ifelse(start.mo == 1, 12, start.mo-1)
>      data.end = as.numeric(format(index(dat)[length(index(dat))], "%m"))
>      mo.end.include = ifelse(end.mo > data.end | end.mo > data.end,
> end.mo - data.end, 12 - abs(end.mo - data.end))
>      data1 = zooreg(c(rep(NA, mo.start.include), coredata(dat),
> rep(NA, mo.end.include)),
>                       as.yearmon(paste(ifelse(start.mo ==
> as.numeric(format(index(dat)[1], "%m")) | start.mo <
> as.numeric(format(index(dat)[1], "%m")),
> as.numeric(format(index(dat)[1], "%Y")),
> as.numeric(format(index(dat)[1], "%Y"))-1),
>                                  ifelse(start.mo < 10,
> paste("0",start.mo,sep=""), as.character(start.mo)), "01", sep="-")),
>                       frequency=12 )
>      df1 = data.frame(QUOTE = coredata(data1),
>                        MONTH = format(index(data1)[1:12], "%b"),
>                        YEAR =  paste("Year",
> rep(1:(length(data1)%/%12), each=12), sep="-"))
>      df1$MONTH = suppressWarnings(relevel(df1[,2], as.vector(df1[,2][1:12])))
>      df1$YEAR = suppressWarnings(relevel(df1[,3], unique(as.vector(df1[,3]))))
>      p = ggplot(df1) + geom_line(aes(y=QUOTE, x=MONTH, group=YEAR,
> colour=YEAR), size=1.2)
>      return(list(dat=df1, p=p)) }
>
> You just need to copy-paste entire code and need to put some daily TS
> as "zoo" object. Here is an example
>
> library(quantmod)   # required to download data from net
> dat = as.zoo(get(getSymbols("^NSEI")))[,4]
> plot(dat)
> seasonalityPlot(dat, 1)
>
> Please note that, here you would have additional option (2nd argument)
> to select the base month, which is by default kept as January (jan =
> 1).
>
> I would also like to know from peers how above function can be
> improved further...................
> _____________________________________________________
>
> Arun Kumar Saha, FRM
> QUANTITATIVE RISK AND HEDGE CONSULTING SPECIALIST
> Visit me at : http://in.linkedin.com/in/ArunFRM
>
> _______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-sig-finance
> -- Subscriber-posting only. If you want to post, subscribe first.
> -- Also note that this is not the r-help list where general R questions should go.
>



--
Jeffrey Ryan
[hidden email]

ia: insight algorithmics
www.insightalgo.com

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Re: Seasonal plot of daily data

Gabor Grothendieck
In reply to this post by SNV Krishna-2
On Tue, Aug 3, 2010 at 2:42 AM, SNV Krishna <[hidden email]> wrote:

> Hi Gabor,
>
> many thanks for the solution and it worked.
>
> I tried a lot in getting appropriate function to extract year or month from
> the date, but could not. Your suggestion of using cut() is great, and I have
> not come across this function. Later I saw on help file, but its usage to
> extract year from date was not mentioned. By the way can you mention any
> other function that are useful in extracting year or month or week number or
> day?


today <- Sys.Date()
as.numeric(format(today, "%Y"))  # see ?strptime
as.POSIXlt(today)$year + 1900)
as.numeric(substr(today, 1, 4))
trunc(as.numeric(as.yearmon(today)))
library(chron); month.day.year(today)$year

Also see R News 4/1 .


>
> also can you tell what is 'seq_along'?

seq_along(x) returns 1, 2, 3, ..., length(x). See ?seq_along

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.