I'm in the process of doing some development for the ggtern package, and I am trying to produce an efficient algorithm to do with ternary heatmaps. Specifically, I am using the following post (Ternary Heatmap) as a startingpoint.
Consider the function below, which is based off (part of) the above link:
# Produce Points for Triangular Mesh
triMesh = function( n = 1){
  n    = max(as.integer(n[1]),1)
  p    = data.frame()
  cnt  = 0
  inc  = 1.0/n
  stp  = seq(0,1,length.out = n + 1 )
  for (ix in seq_along(stp)){
    z <- stp[ix]
    y <- 1 - z
    x <- 0
    while ( y >= 0 ) {
      p   <- rbind(p, c(cnt, x, y, z))
      y   <- y - inc #Step x down
      x   <- x + inc #Step y up
      cnt <- cnt + 1          #Increment Count
    }
  }
  colnames(p) = c("IDPoint","x","y","z")
  p = round(p[with(p,order(y,x,-z)),],6)
  rownames(p) = 1:nrow(p) - 1
  p
}
AND here is my version, which is syntactically much more concise:
# Produce Points for Triangular Mesh
triMesh2 = function( n = 1 ){
  n   = as.integer(max(n[1],1))
  #Nested plyr calls
  result = ldply(0:n,function(y){ ##OUTER
    ldply(0:(n-y),function(x){    ##INNER
      data.frame(x,y,z = n -x -y) ##DIFF
    })
  })
  result        = data.frame( 1:nrow(result)-1,result/n)
  names(result) = c('IDPoint','x','y','z')
  result
}
Now, using microbenchmark the first algorithm finishes several times faster:
> microbenchmark(triMesh(10))
Unit: milliseconds
        expr      min      lq     mean   median       uq      max neval
 triMesh(10) 6.447525 6.91798 8.432698 7.334905 8.727805 23.37242   100
> microbenchmark(triMesh2(10))
Unit: milliseconds
         expr      min       lq     mean   median       uq     max neval
 triMesh2(10) 27.26659 29.34891 32.50808 31.43524 34.92925 51.8585   100
> 
I was wondering if anyone can improve the performance of the second algorithm to something in the vicinity of the first one (or better)...
Cheers