[R] passing function parameters into a 'with' statement to dynamically pick out columns

William Dunlap wdunlap at tibco.com
Wed Jun 20 18:21:03 CEST 2012


> What I'd like to do is something like this:
> 
> perc.mktshare <- function(df, scaling.column){  
>  range1 <- floor(min(with(df, 100*scaling.column/all)))
>  range2 <- ceiling(max(with(df, 100*scaling.column/all)))  
>  with(df,plot(date,100*"scaling.column"/all,ylim=c(range1,range2),ylab="% Marketshare"))
> }
> perc.mktshare(pmts,"ind")
> perc.mktshare(pmts,"maj")

When writing functions avoid using "convenience" functions that do nonstandard
evaluation (e.g., with() and subset()) and use the subsetting operators, "[", "[[", and "$",
instead:

perc.mktshare <- function(df, # a data.frame, must contain column called "date"
                                                scaling.column # "quoted" name of column in df
                                               ) {
    scaledColumn <- 100 * df[,scaling.column] / df[,"all"]
    range1 <- floor(min(scaledColumn))
    range2 <- ceiling(max(scaledColumn))
    plot(df[,"date"], scaledColumn, ylim=c(range1, range2), ylab=paste("%Marketshare of", scaling.column), xlab="date")
}

E.g.,
> df <- data.frame(date=1:10, CatFood=101:110, DogFood=120:111)
> df$all <- rowSums(df[,-1])
> perc.mktshare(df, "CatFood") # upward trending plot
> perc.mktshare(df, "DogFood") # downward trending plot
> perc.mktshare(df, "GoatChow") # error: "Undefined columns selected"

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com


> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf
> Of peter dalgaard
> Sent: Wednesday, June 20, 2012 9:01 AM
> To: David Marx
> Cc: 'r-help at r-project.org'
> Subject: Re: [R] passing function parameters into a 'with' statement to dynamically pick
> out columns
> 
> 
> On Jun 20, 2012, at 16:45 , David Marx wrote:
> 
> > Hi,
> >
> > I've built a function to generate plots and would like to be able pass in column names
> as a parameter. Here's a boiled down version of what I have right now:
> >
> > pmts <- data.frame(date=c(1,2,3), all=c(5,6,7),maj=c(4,5,6),ind=c(3,4,5))
> > perc.mktshare <- function(df){
> >  range1 <- floor(min(with(df, 100*ind/all)))
> >  range2 <- ceiling(max(with(df, 100*ind/all)))
> >  with(df,plot(date,100*ind/all,ylim=c(range1,range2),ylab="% Marketshare"))
> > }
> > perc.mktshare(pmts)
> >
> > What I'd like to do is something like this:
> >
> > perc.mktshare <- function(df, scaling.column){
> >  range1 <- floor(min(with(df, 100*scaling.column/all)))
> >  range2 <- ceiling(max(with(df, 100*scaling.column/all)))
> >  with(df,plot(date,100*"scaling.column"/all,ylim=c(range1,range2),ylab="%
> Marketshare"))
> > }
> > perc.mktshare(pmts,"ind")
> > perc.mktshare(pmts,"maj")
> >
> > I've tried going about this a couple of different ways but I can't make it work. My
> suspicion is that there's probably no way to do this using the 'with' statement and I'll
> have to trim the input dataframe to the pertinent columns first using subset or
> something.
> >
> 
> Something with eval(bquote(.....)) should do it, e.g.
> 
> foo <- function(col) eval(bquote(with(airquality, plot(.(col), Ozone))))
> foo(quote(Wind))
> foo(quote(Solar.R))
> 
> Or, use .(as.name(col)) inside bquote, and foo("Wind") in the call.
> 
> Possibly, substitute() can be used as well, but it might get tricky.
> 
> 
> 
> > Thanks for your help!
> >
> > David
> >
> > ______________________________________________
> > R-help at r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-help
> > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> > and provide commented, minimal, self-contained, reproducible code.
> 
> --
> Peter Dalgaard, Professor
> Center for Statistics, Copenhagen Business School
> Solbjerg Plads 3, 2000 Frederiksberg, Denmark
> Phone: (+45)38153501
> Email: pd.mes at cbs.dk  Priv: PDalgd at gmail.com
> 
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list