I assume what you want is not the last data value in each month
labelled with the nth day of the month (or the last day of the month
if there are fewer than n days) but the last day in the data that is
on or prior to the nth of the month. If that is what you want then
try this.
nth.of.month <- function(x, n = 31) {
tt <- as.Date(time(x))
ix <- as.numeric(format(tt, "%d")) <= n
last.ix <- c(tapply(seq_along(ix), as.yearmon(tt), tail, 1))
if (length(dim(x)) == 2) x[last.ix,] else x[last.ix]
}
out <- nth.of.month(DJd)
After converting to Date class ix is set to the be the logical vector
which is TRUE on or before the nth of the month and FALSE otherwise.
tapply is used to pick off the index of the last of these in each
month giving last.ix. This is then used to subscript x.
Note that if there are no data points in a month on or prior to day n
of the month then no data for that month will appear.
On Mon, Apr 12, 2010 at 2:53 AM, Research <risk2009 at ath.forthnet.gr>
wrote:> Dear Gabor,
>
> Thanks for your reply. however:
>
>> tail(DJd)
> ?????????? ^DJI.Close
> 2010-04-01?? 10927.07
> 2010-04-05?? 10973.55
> 2010-04-06?? 10969.99
> 2010-04-07?? 10897.52
> 2010-04-08?? 10927.07
> 2010-04-09?? 10997.35
>> tail(ag)
>
> 2009-11-30 10344.84
> 2009-12-31 10428.05
> 2010-01-31 10067.33
> 2010-02-28 10325.26
> 2010-03-31 10856.63
> 2010-04-30 10997.35
>
> It seems the script "makes up" dates (?)
>
> Best,
> Costas
>
> On 09/04/2010 14:55, Gabor Grothendieck wrote:
>
> The function seems to be working properly. You are asking for a day
> of the month which does not exist. I assume this was written a very
> long time ago since there are easier ways to do this now. yearmon
> class gives an object representing the year and month of a date and if
> ym is such an object then as.Date(ym) gives the first of the month and
> as.Date(ym, frac = 1) gives the last of the month so:
>
> # nth day of month or last day of month if less
> nth.of.month <- function(date, n) {
> ym <- as.yearmon(date)
> pmin(as.Date(ym) + n - 1, as.Date(ym, frac = 1))
> }
>
> ag <- aggregate(DJd, nth.of.month(time(DJd), 31), tail, 1)
>
>
>
> On Fri, Apr 9, 2010 at 7:01 AM, Research <risk2009 at
ath.forthnet.gr> wrote:
>
>
> Dear all,
>
> Some time ago I received some very kind ?help (special thanks to Gabor) to
> construct a function that isolates the n'th ? working day of each month
for
> zoo object (time series) to create monthly data from daily observations.
>
> I found out that the code works fine except for the 29 till 31st dates of
> each month as it skips some months (February for example).
>
> If ?you could help me isolate the problem I would be grateful as I can not
> find a way to explain to R to keep the last ?working day of month if I
> choose the 29th, 30th or 31st dates...
>
> I enclose ?a working version of the function and a script for demo
purposes.
>
> Many thanks in advance,
> Costas
>
> library(fImport)
> library(zoo)
> DJ<-yahooSeries("^DJI", frequency="daily",
nDaysBack=10000)
> DJd<-as.zoo(DJ[,4])
>
> ### Choose number of day for month
>
> chooseday<-function(z, day)
>
> ? ?{
>
> ? ?# z.na is same as z but with missing days added using NAs
> ? ?# Its formed by merging z with a zoo-width series containing all days.
>
> ? ?rng <- range(time(z))
> ? ?z.na <- merge(z, zoo(, seq(rng[1], rng[2], by = "day")))
>
> ? ?# form a series that has NAs wherever z.na does but has 1, 2, 3, ...
> ? ?# instead of z.na's data values and then use na.locf to fill in NAs
>
> ? ?idx <- na.locf(seq_along(z.na) + (0 * z.na))
>
> ? ?# pick off elements of z.na corresponding to i'th of month
>
> ? ?noofday <- paste(day)
>
> ? ?if (day<10) noofday<-paste("0",day, sep="")
>
> ? ?tempdata<-z.na[idx[format(time(z.na), "%d") == noofday]]
>
> ? ?return(tempdata)
>
> ? ?}
>
> length(chooseday(DJd,1))
> length(chooseday(DJd,2))
> length(chooseday(DJd,31))
> length(chooseday(DJd,30))
> length(chooseday(DJd,29))
> length(chooseday(DJd,28))
> tail(chooseday(DJd,31))
>
>
>
>
>
>
>
>
>
>
>