【问题标题】:Giving arguments from "..." argument to right function in R [duplicate]将“...”参数的参数提供给R中的正确函数[重复]
【发布时间】:2016-10-23 23:06:08
【问题描述】:

我有一个函数来计算分类变量和连续变量的矩阵的相关性:

correlation <- function(matrix, ...) {
    xx <- do.call(rbind, lapply(colnames(mtrc), function(ex_i) {
        ty_i <- wtype(matrix, ex_i)
        yy <- sapply(colnames(mtrc), function(ex_j) {
            ty_j <- wtype(matrix, ex_j)

            if(ty_i == "numeric" & ty_j == "numeric") {
                cor(mtrc[ , c(ex_i, ex_j)], ...)[1, 2]
            } else if(ty_i == "factor" & ty_j == "factor") {
                cramersV(table(mtrc[ , c(ex_i, ex_j)]), ...)
            } else {
                fm <- paste(ex_i, "~", ex_j)
                if(ty_i == "factor") {
                    fm <- paste(ex_j, "~", ex_i)
                }
                fm <- lm(fm, data = mtrc[ , c(ex_i, ex_j)], ...)
                lm.beta(fm)
            }
        })
        names(yy) <- colnames(mtrc)
        yy
    }))
    rownames(xx) <- colnames(mtrc)
    xx
}

我的问题是如何正确地将参数... 传递给corcramerVlm。如果用户为cor 提供参数并且矩阵中有分类变量,则这三个函数的参数名称不匹配,因此cramerVlm 会引发错误(未使用的参数.. .).

所以...我愿意接受您可以提出的任何解决方案或想法。

【问题讨论】:

  • 执行dots &lt;- list(...) 并检查,例如,哪些元素与formalArgs(lm) 匹配并将列表子集到这些元素。将fmdata 参数添加到此列表并使用do.call 调用lm。我会告诉你怎么做,但你没有提供一个可重复的例子。
  • 您可能还会在pryr 包中找到对此类任务有用的函数dotsnamed_dots

标签: r arguments parameter-passing


【解决方案1】:

当我在下面回答时,我没有意识到 Richard Scriven 在 2014 年提出了一个很好的问题:Split up `...` arguments and distribute to multiple functions。所以是的,这是一个重复的问题。但我会在这里保留我的答案,因为它代表了我的想法(以及我的想法)。


原答案

我认为这更好,通过给你的correlation 函数一个更好的控制:

correlation <- function(matrix, cor.opt = list(), cramersV.opt = list(), lm.opt = list()) {
    xx <- do.call(rbind, lapply(colnames(mtrc), function(ex_i) {
        ty_i <- wtype(matrix, ex_i)
        yy <- sapply(colnames(mtrc), function(ex_j) {
            ty_j <- wtype(matrix, ex_j)

            if(ty_i == "numeric" & ty_j == "numeric") {
                do.call("cor", c(list(x = mtrc[ , c(ex_i, ex_j)]), cor.opt))[1, 2]
            } else if(ty_i == "factor" & ty_j == "factor") {
                do.call("cramersV", c(list(x = table(mtrc[ , c(ex_i, ex_j)])), cramersV.opt))
            } else {
                fm <- paste(ex_i, "~", ex_j)
                if(ty_i == "factor") {
                    fm <- paste(ex_j, "~", ex_i)
                }
                fm <- do.call("lm", c(list(formula = fm, data = mtrc[ , c(ex_i, ex_j)]), lm.opt))
                lm.beta(fm)
            }
        })
        names(yy) <- colnames(mtrc)
        yy
    }))
    rownames(xx) <- colnames(mtrc)
    xx
}

您可以通过参数cor.optcramersV.optlm.opt 传递用于不同函数的不同参数。然后,在您的函数 correlation 中,使用 do.call() 进行所有相关的函数调用。


评论

我喜欢@Roland 的想法。他选择使用...,同时根据不同函数的形式参数拆分list(...)。另一方面,我要求您手动将这些参数指定到不同的列表中。最后,我们都要求你使用do.call()进行函数调用。

Roland 的想法适用范围很广,因为它更容易扩展到更多需要... 的功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    • 2019-03-26
    • 1970-01-01
    • 2021-11-29
    • 2019-03-29
    • 2017-12-06
    • 2020-10-30
    相关资源
    最近更新 更多