Is there any way to pass generic column names to functions like xtabs
in R?
Typically, I'm trying to do something like:
xtabs(weight ~ col, data=dframe)
with col
and weight
two columns of my data.frame
, weight
being a column containing weights. It works, but if I want to wrap xtabs
in a function to which I pass the column names as argument, it fails. So, if I do:
xtabs.wrapper <- function(dframe, colname, weightname) {
return(xtabs(weightname ~ colname, data=dframe))
}
it fails. Is there a simple way to do something similar? Perhaps I'm missing something with R logic, but it seems to me quite annoying not to be able to pass generic variables to such functions since I'm not particularly fond of copy/paste.
Any help or comments appreciated!
Edit: as mentioned in comments, I was suggested to use eval
and I came with this solution:
xtabs.wrapper <- function(dframe, wname, cname) {
xt <- eval(parse(text=paste("xtabs(", wname, "~", cname, ", data=",
deparse(substitute(dframe)), ")")))
return(xt)
}
As I said, I seems to me to be an ugly trick, but I'm probably missing something about the language logic.
Not sure if this is any prettier, but here is a way to define a function without using eval
... it involves accessing the correct columns of dframe
via []
:
xtabs.wrapper <- function(dframe, wname, cname) {
tmp.wt <- dframe[,wname]
tmp.col <- dframe[,cname]
xt <- xtabs(tmp.wt~tmp.col)
return(xt)
}
Or you can shorten the guts of the function to:
xtabs.wrapper2 <- function(dframe, wname, cname) {
xt <- xtabs(dframe[,wname]~dframe[,cname])
return(xt)
}
To show they are equivalent here with an example from the mtcars
data:
data(mtcars)
xtabs(wt~cyl, mtcars)
xtabs.wrapper(mtcars, "wt", "cyl")
xtabs.wrapper2(mtcars, "wt", "cyl")
I did this once:
creatextab<-function(factorsToUse, data)
{
newform<-as.formula(paste("Freq ~", paste(factorsToUse, collapse="+"), sep=""))
xtabs(formula= newform, drop.unused.levels = TRUE, data=data)
}
Obviously this is a different form because of the Freq, but basically .. you can generate the forumula as a string and then you are just using xtabs()
directly.
If you want an n-way crosstab and cname contains a string of variable names, then you'll want the following:
xtabs.wrapper3 <- function(dframe, wname, cname) {
eval(cname)
formula <- paste0(wname, " ~ ", paste0(cname, collapse=" + ") )
xt <- xtabs(formula, data = dframe)
return(xt)
}
xtabs.wrapper3(mtcars, "wt", c("cyl", "vs"))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.