Friday, September 16, 2011

Performance with ggplot2

Now after Reporting Good Enough to Share, let’s use ggplot2 and PerformanceAnalytics to turn this


into this

From TimelyPortfolio

I have been notified that the colors aren’t great.  How does everyone like this?

R code (click to download):

require(PerformanceAnalytics)   clientPerf <- read.csv("clientperf.csv",stringsAsFactors=FALSE)
clientPerf[,2:NCOL(clientPerf)] <- lapply(clientPerf[,2:NCOL(clientPerf)],as.numeric)
clientPerf <- as.xts(clientPerf[,2:NCOL(clientPerf)]/100, = as.Date(clientPerf[,1],format="%m-%d-%y"))
colnames(clientPerf) <- c("Client","BarclaysAgg","SP500")     returns.cumul <- xts(apply((1+clientPerf),MARGIN=2,FUN=cumprod),
returns.cumul.Melt <- melt(,
colnames(returns.cumul.Melt) <- c("Date","Portfolio","Growth")
aes(x=Date,y=Growth,colour=Portfolio)) +
geom_line(lwd=1) +
scale_x_date() +
scale_colour_manual(values=c("cadetblue","darkolivegreen3","gray70","bisque3","purple")) +
theme_bw() +
labs(x = "", y = "") +
opts(title = "Cumulative Returns",plot.title = theme_text(size = 20, hjust = 0))   returnTable <- table.TrailingPeriods(clientPerf,
rownames(returnTable) <- c(paste(c(1:3)," Year",sep=""),"Since Inception")
returnMelt <- melt(cbind(rownames(returnTable),returnTable*100))
b<-ggplot(returnMelt, stat="identity",
aes(x=Period,y=Value,fill=Portfolio)) +
geom_bar(position="dodge") +
scale_fill_manual(values=c("cadetblue","darkolivegreen3","gray70")) +
theme_bw() +
labs(x = "", y = "") +
opts(title = "Returns (annualized)",plot.title = theme_text(size = 20, hjust = 0))     downsideTable<-table.DownsideRisk(clientPerf)[c(1,3,5,7,8),]
c<-ggplot(downsideMelt, stat="identity",
aes(x=Statistic,y=Value,fill=Portfolio)) +
geom_bar(position="dodge") + coord_flip() +
scale_fill_manual(values=c("cadetblue","darkolivegreen3","gray70")) +
theme_bw() +
labs(x = "", y = "") +
opts(title = "Risk Measures",plot.title = theme_text(size = 20, hjust = 0))
#geom_hline(aes(y = 0))
#opts(axis.line = theme_segment(colour = "red"))
#opts(panel.grid.major = theme_line(linetype = "dotted"))   #jpeg(filename="performance ggplot.jpg",quality=100,width=6.5, height = 8, units="in",res=96)
#pdf("perf ggplot.pdf", width = 8.5, height = 11)   grid.newpage()
pushViewport(viewport(layout = grid.layout(3, 1)))   vplayout <- function(x, y)
viewport(layout.pos.row = x, layout.pos.col = y)
print(a, vp = vplayout(1, 1))
print(b, vp = vplayout(2, 1))
print(c, vp = vplayout(3, 1))

Created by Pretty R at


  1. This is a great blog, thanks for posting this! I'm just learning R and your blog is a fantastic learning source.

    Is possible to download your "clientperf.csv" file?

  2. Sorry I did not make the download clear. You can click the picture of the csv or the link is

  3. Right after the call on line 25:

    returnTable <- table.TrailingPeriods(clientPerf,

    I receive the error:

    Error in periodicity(R) : can not calculate periodicity of 1 observation

    I'm new to R, so I'm not sure why there is only 1 observation. Any idea?


  4. thanks for reading and commenting. I am not sure, but it appears like the file is not being read properly. See instructions above for downloading the file. Then in the line

    clientPerf <- read.csv("clientperf.csv",stringsAsFactors=FALSE)

    put in the path where the file exists. For instance, if you put the file in c:\\windows\temp, then the line should read

    clientPerf <- read.csv("c:\\windows\\temp\\clientperf.csv",stringsAsFactors=FALSE)

    just do print(clientPerf) to make sure the read worked.

    Let me know if this still does not fix things. Keep playing in R. It is a fantastic tool.

  5. Thanks for the tip.

    I was reading the data file, but I found a couple of issues between the data and the script:

    - The date format in the data file doesn't seem to match the pattern in the script (format="%m-%d-%y").
    - The negative values in column three of the data file seem to cause some warnings because the negative value is indicated by () rather than a negative sign.

    I changed the script date pattern to %m/%d/%y and that resolved the periodicity error, but now the Returns (Annualized) chart is not displaying. I'm getting an error in data.frame.

    I'll post anything I discover.

    BTW, I'm using RStudio with R version 2.13.1 (32 bit).

  6. looks like Google docs converts .csv. Try redownloading. I uploaded as .txt this time. That way dates and numbers are in R generic format.

    Thanks for catching that.