[R] How to pass in a list of variables as an argument to a function?

Joshua Wiley jwiley.psych at gmail.com
Sun Jan 1 23:39:47 CET 2012


Hi Randall,

This will do it.  There may be more elegant ways.  Formula methods are
just handy front ends (e.g., stats:::aggregate.formula), that end up
dispatching to other methods usually.  It is easy to pass a character
vector to extractor functions like `[`() so with a bit more typing,
you can often skip the formula altogether.  I think that will be the
easiest approach if you are not actually typing the formula (there are
ways to create them, but bleh).

Cheers,

Josh

###########################################

# libraries used
library(reshape)

# create some data similar to use case
myData = data.frame(expand.grid(varA=c("a", "b", "c"),
varB=c("d", "e", "f"),
varC=c("g", "h", "i"),
varD=c("old", "new")),
n=1000, fail=rbinom(2700,1000, 0.01))

# add in one more column
myData$pass = with(myData, n - fail)

# List of grouping vars.  I would like to pass this object around and
use it as arguments in functions
myGroupVars = c("varA", "varB", "varC")

# create a new column that is the combination of the grouping vars
(used in plotting with lattice)
# Question 1:  Is there a way to replace "varA, varB, varC" in the
function below with an object?
myData2 <- transform(myData, groupVar = do.call("paste", c(myData[,
myGroupVars], sep = " | ")))
myData = transform(myData, groupVar = paste(varA, varB, varC, sep = " | "))

all.equal(myData, myData2)

# Sum the data by the same groupVars and two other variables
# Question 2:  Is there a way to replace "varA + varB + varC" in the
function below and do the same aggregation?
myDataSum = aggregate(cbind(pass, fail) ~ varA + varB + varC +
groupVar + varD, data = myData, sum)

myDataSum2 <- aggregate(x = myData2[, c("pass", "fail")],
  by = myData2[, c(myGroupVars, "groupVar", "varD")], FUN = sum)

all.equal(myDataSum, myDataSum2)

# pivot the pass and fail quantity to one row per group,  labelling them
# Question 3:  This one actually works.  idvar happily accepted the
vector of group vars.  Better way?
myDataSum <- reshape(myDataSum,  idvar = myGroupVars, v.names =
c("pass", "fail"),
timevar = "varD", direction = "wide")
#####################################

On Sun, Jan 1, 2012 at 11:58 AM, Randall Goodwin
<randall.goodwin at gmail.com> wrote:
> Hello,
>
> I have some code that currently works fine and I am endeavoring to
> convert the major pieces of it into functions.
> This involves taking "hard coded" names of variables that are used in
> various places and figuring out how to
> abstract them out into functions where the arguments (i.e. a list of
> variables) can be passed to the parent function
> and used within that function for various purposes.
>
> Here is some code that comes close to replicating some of the cases I
> am trying to solve.
>
> Basically,  the same list of variables comes up many times in the
> current code (where nothing is really a function).
> Now that I am converting everything to a function, I'd like to specify
> the list of variables once and use that list
> throughout the code in other places.  The list of variables does not
> have to be of class = list.  more generally,
> it could be any class that can be converted such that it is usable in
> paste(), aggregate() and reshape() as in
> the example below.
>
> I have tried various things to make it work.. using paste() and
> noquote() in combination to build a string that is identical to the
> arguments that these functions accept,  however R interprets them as a
> string,  not as individual arguments.
>
> Thanks in advance,
>
> Randall
>
> #################################################################
>
> # libraries used
> library(reshape)
>
> # create some data similar to use case
> myData = data.frame(expand.grid(varA=c("a", "b", "c"),
> varB=c("d", "e", "f"),
> varC=c("g", "h", "i"),
> varD=c("old", "new")),
> n=1000, fail=rbinom(2700,1000, 0.01))
>
> # add in one more column
> myData$pass = myData$n-myData$fail
>
> # List of grouping vars.  I would like to pass this object around and
> use it as arguments in functions
> myGroupVars = c("varA", "varB", "varC")
>
> # create a new column that is the combination of the grouping vars
> (used in plotting with lattice)
> # Question 1:  Is there a way to replace "varA, varB, varC" in the
> function below with an object?
> myData = transform(myData, groupVar = paste(varA, varB, varC, sep = " | "))
>
> # Sum the data by the same groupVars and two other variables
> # Question 2:  Is there a way to replace "varA + varB + varC" in the
> function below and do the same aggregation?
> myDataSum <- aggregate(cbind(pass, fail) ~ varA + varB + varC +
> groupVar + varD, data = myData, sum)
>
> # pivot the pass and fail quantity to one row per group,  labelling them
> # Question 3:  This one actually works.  idvar happily accepted the
> vector of group vars.  Better way?
> myDataSum <- reshape(myDataSum,  idvar = myGroupVars, v.names =
> c("pass", "fail"),
> timevar = "varD", direction = "wide")
>
> ______________________________________________
> 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.



-- 
Joshua Wiley
Ph.D. Student, Health Psychology
Programmer Analyst II, Statistical Consulting Group
University of California, Los Angeles
https://joshuawiley.com/



More information about the R-help mailing list