简体   繁体   English

将通用列名传递给 R 中的 xtabs 函数

[英]Pass generic column names to xtabs function in R

Is there any way to pass generic column names to functions like xtabs in R?有没有办法将通用列名传递给 R 中的xtabs函数?

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.我的data.frame colweight两列, weight是包含权重的列。 It works, but if I want to wrap xtabs in a function to which I pass the column names as argument, it fails.它有效,但如果我想将xtabs包装在我将列名作为参数传递给的函数中,它会失败。 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.也许我在 R 逻辑中遗漏了一些东西,但在我看来,不能将通用变量传递给这些函数似乎很烦人,因为我不是特别喜欢复制/粘贴。

Any help or comments appreciated!任何帮助或意见表示赞赏!

Edit: as mentioned in comments, I was suggested to use eval and I came with this solution:编辑:正如评论中提到的,我被建议使用eval并且我提供了这个解决方案:

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 [] :不确定这是否更漂亮,但这里有一种不使用eval定义函数的方法……它涉及通过[]访问dframe的正确列:

    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:mtcars数据中的一个例子来表明它们在这里是等效的:

    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.显然,由于 Freq,这是一种不同的形式,但基本上……您可以将论坛生成为字符串,然后您只需直接使用xtabs()

If you want an n-way crosstab and cname contains a string of variable names, then you'll want the following:如果您想要一个 n 路交叉表并且 cname 包含一串变量名称,那么您将需要以下内容:

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"))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM