Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Basic calendar display in R

Tags:

date

r

calendar

Is there a basic calendar display in R, like Unix's cal program?

I realize it's not that hard to wrap the base date/time functions (like weekdays, seq.date, etc.), but I feel like I'm ignorant of something pretty basic that may be solved in one of the outstanding time/date packages that already exist. Moreover, it always starts simply enough: assign days of the week, but then one gets to leap years, layout for calendars spanning multiple months (though I'd settle for just printing 1 month), and so on.

My current usage involves switching out of R to Linux or a calendar program in Windows. Doing this in R would be easier.


Note 1. I've looked at some of the various widgets available for Gtk2 and TclTk - for some reason, installation of supporting systems is not working out well (and I think it's serious overkill, nor is it very good from a portability perspective to have such dependencies). In Windows, I've even tried Cygwin, to access cal, but that installation seems to be conflicting with Rtools. In short, adding layers of stuff is not a particularly productive avenue at the moment. :) I've not found any solutions in lubridate, xts, zoo, and other packages, though I may have missed something.

like image 795
Iterator Avatar asked Oct 27 '11 17:10

Iterator


1 Answers

Here is a function that will do the basic yearly or monthly calendar:

cal <- function(month, year) {

        if(!require(chron)) stop('Unable to load chron package')

     if(missing(year) && missing(month)) {
         tmp <- month.day.year(Sys.Date())
         year <- tmp$year
         month <- tmp$month
     }


    if(missing(year) || missing(month)){  # year calendar
        if(missing(year)) year <- month
        par(mfrow=c(4,3))
        tmp <- seq.dates( from=julian(1,1,year), to=julian(12,31,year) )
        tmp2 <- month.day.year(tmp)
        wd <- do.call(day.of.week, tmp2)
        par(mar=c(1.5,1.5,2.5,1.5))
        for(i in 1:12){
            w <- tmp2$month == i
            cs <- cumsum(wd[w]==0)
            if(cs[1] > 0) cs <- cs - 1
            nr <- max( cs ) + 1
            plot.new()
            plot.window( xlim=c(0,6), ylim=c(0,nr+1) )
            text( wd[w], nr - cs -0.5 , tmp2$day[w] )
            title( main=month.name[i] )
            text( 0:6, nr+0.5, c('S','M','T','W','T','F','S') )
        }

    } else {  # month calendar

        ld <- seq.dates( from=julian(month,1,year), length=2, by='months')[2]-1
        days <- seq.dates( from=julian(month,1,year), to=ld)
        tmp <- month.day.year(days)
        wd <- do.call(day.of.week, tmp)
        cs <- cumsum(wd == 0)
        if(cs[1] > 0) cs <- cs - 1
        nr <- max(cs) + 1
        par(oma=c(0.1,0.1,4.6,0.1))
        par(mfrow=c(nr,7))
        par(mar=c(0,0,0,0))
        for(i in seq_len(wd[1])){ 
            plot.new()
            #box()
        }
        day.name <- c('Sun','Mon','Tues','Wed','Thur','Fri','Sat')
        for(i in tmp$day){
            plot.new()
            box()
            text(0,1, i, adj=c(0,1))
            if(i < 8) mtext( day.name[wd[i]+1], line=0.5,
                at=grconvertX(0.5,to='ndc'), outer=TRUE ) 
        }
        mtext(month.name[month], line=2.5, at=0.5, cex=1.75, outer=TRUE)
        #box('inner') #optional 
    }
}

You can edit various pieces to customize it. You can use par(mfg=c(r,c)) to add text, plots, or other info to a given cell in the monthly calendar (see updateusr and subplot in the TeachingDemos package for possible aid in adding a plot).

Here are some examples of adding text or plots to the calendar:

cal(10,2011)
par(mfg=c(3,2))  # monday oct 10
text(.5,.5, 'Some\nText', cex=2)

par(mfg=c(2,3)) #Tues oct 4
text(1,1, 'Top Right', adj=c(1,1))

par(mfg=c(2,4)) # Wed oct 5
text(0,0, 'Bottom Left', adj=c(0,0))

par(mfg=c(6,2)) # oct 31
tmp.x <- runif(25)
tmp.y <- rnorm(25,tmp.x,.1)
par(usr=c( range(tmp.x), range(tmp.y) ) )
points(tmp.x,tmp.y)
like image 193
Greg Snow Avatar answered Oct 21 '22 15:10

Greg Snow