edply: combining plyr and expand.grid
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Here’s a code snippet I thought I’d share. Very often I find myself checking the output of a function f(a,b) for a lot of different values of a and b, which I then need to plot somehow.
An example: here’s a function that computes the value of a sinusoidal function on a grid of points, and returns a data.frame.
fun <- function(freq,phase) { x <- seq(0,2*pi,l=100); data.frame(x=x,value=sin(freq*x-phase)) }
It takes a frequency and a phase argument, and we want to know what the output looks like for frequencies between 1 and 6 and phase values of 0 and 1.
Usually this means calling e.g., expand.grid(freq=1:6,phase=c(0,1)), to get all possible combinations of the two variables, then calling one of the plyr functions to get the results in a useable form. The edply function does it all in one line:
d <- edply(list(freq=c(1,2,4,8),phase=c(0,1)),fun)
which returns a data.frame:
> head(d,3)
freq phase x value
1 1 0 0.00000000 0.00000000
2 1 0 0.06346652 0.06342392
3 1 0 0.12693304 0.12659245
which we can then plot:
ggplot(d,aes(x,value,col=as.factor(phase)))+facet_wrap( ~ freq)+geom_path()
The edply function can also be used to compute and plot a heatmap:
fun <- function(x,y) dnorm(x)*dnorm(y)*sin(x) d <- edply(list(x=seq(-3,3,l=40),y=seq(-3,3,l=40)),fun) ggplot(d,aes(x,y))+geom_raster(aes(fill=V1))
I’ve attached the code below, there really isn’t much to it. Note that there’s also an “elply” function that (not unexpectedly) returns a list.
#eply: combining plyr and expand.grid. #Simon Barthelmé, University of Geneva # #Example usage #------------- #fun <- function(x,y) dnorm(x)*dnorm(y)*sin(x) #d <- edply(list(x=seq(-3,3,l=40),y=seq(-3,3,l=40)),fun) #ggplot(d,aes(x,y))+geom_raster(aes(fill=V1)) #Heatmap of f(x,y) elply <- function(vars,fun,...,.progress="none",.parallel=FALSE) { df <- do.call("expand.grid",vars) if (all(names(vars) %in% names(formals(fun)))) { #We assume that fun takes the variables in vars as named arguments funt <- function(v,...) { do.call(fun,c(v,list(...))) } res <- alply(df,1,funt,...,.progress=.progress,.parallel=.parallel) } else { #We assume that fun takes a named list as first argument res <- alply(df,1,fun,...,.progress=.progress,.parallel=.parallel) } res } edply <- function(...) { res <- elply(...) plyr:::list_to_dataframe(res,attr(res, "split_labels")) }
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.