Предоставление аргументов из аргумента "..." для правильной функции в R

У меня есть функция для вычисления корреляции матрицы как категориальных, так и непрерывных переменных:

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
}

Мой вопрос, как правильно передать аргумент ... в cor, cramerV а также lm, Поскольку имена аргументов этих трех функций не совпадают, если пользователь дает аргумент для cor и есть матричная переменная в матрице, cramerV или же lm выдает ошибку (неиспользованный аргумент...).

Итак... Я открыт для любого решения или идеи, которые вы можете иметь.

1 ответ

Я не осознавал, что у Ричарда Скривена в 2014 году был отличный вопрос: разделить аргументы `...` и распределить их по нескольким функциям, когда я сделал свой ответ ниже. Так что да, это дублированный вопрос. Но я оставлю здесь свой ответ, поскольку он представляет то, что я думал (и что я думаю).


Оригинальный ответ

Я думаю, что это лучше, давая 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.opt, cramersV.opt а также lm.opt, Тогда внутри вашей функции correlationиспользовать do.call() для всех соответствующих функций вызова.


Комментарий

Мне нравится идея @Roland. Он выбирает использовать ...во время расщепления list(...) в соответствии с формальными аргументами различных функций. С другой стороны, я попросил вас вручную указать эти аргументы в разных списках. В конце концов, мы оба просим вас использовать do.call() для вызова функции.

Идея Роланда широко применима, так как ее легче распространить на большее количество функций, требующих ...,

Другие вопросы по тегам