Что делает match.call ()? - PullRequest
       12

Что делает match.call ()?

1 голос
/ 04 октября 2019

Я пытаюсь вручную перевести некоторый R-код в Python и обнаружил следующий фрагмент:

"drm" <- function(
formula, curveid, pmodels, weights, data = NULL, subset, fct,
type = c("continuous", "binomial", "Poisson", "quantal", "event"), bcVal = NULL, bcAdd = 0,
start, na.action = na.omit, robust = "mean", logDose = NULL,
control = drmc(), lowerl = NULL, upperl = NULL, separate = FALSE,
pshifts = NULL)
{
    ## ... elided ...

    ## Storing call details
    callDetail <- match.call()

    ## Handling the 'formula', 'curveid' and 'data' arguments
    anName <- deparse(substitute(curveid))  # storing name for later use
    if (length(anName) > 1) {anName <- anName[1]}  # to circumvent the behaviour of 'substitute' in do.call("multdrc", ...)
    if (nchar(anName) < 1) {anName <- "1"}  # in case only one curve is analysed


    mf <- match.call(expand.dots = FALSE)
    nmf <- names(mf)
    mnmf <- match(c("formula", "curveid", "data", "subset", "na.action", "weights"), nmf, 0)

    mf[[1]] <- as.name("model.frame")
    mf <- eval(mf[c(1,mnmf)], parent.frame())  #, globalenv())
    mt <- attr(mf, "terms")

    dose <- model.matrix(mt, mf)[,-c(1)]  # with no intercept
    resp <- model.response(mf, "numeric")

    origDose <- dose
    origResp <- resp  # in case of transformation of the response
    lenData <- length(resp)
    numObs <- length(resp)

    xDim <- ncol(as.matrix(dose))
    varNames <- names(mf)[c(2, 1)]
    varNames0 <- names(mf)

    # only used once, but mf is overwritten later on

    ## Retrieving weights
    wVec <- model.weights(mf)
    if (is.null(wVec))
    {
        wVec <- rep(1, numObs)
    }

    ## Finding indices for missing values
    missingIndices <- attr(mf, "na.action")
    if (is.null(missingIndices)) {removeMI <- function(x){x}} else {removeMI <- function(x){x[-missingIndices,]}}

    ## Handling "curveid" argument
    assayNo <- model.extract(mf, "curveid")
    if (is.null(assayNo))  # in case not supplied
    {
        assayNo <- rep(1, numObs)
    }
    uniqueNames <- unique(assayNo)
    colOrder <- order(uniqueNames)
    uniqueNames <- as.character(uniqueNames)
    # ...
}

Что это делает? Я вижу в документации для match.call(), что

match.call возвращает вызов, в котором все указанные аргументы указаны их полными именами.

Но я не понимаю, что это значит. Что такое «вызов» в этом контексте? Что означает, что «аргументы задаются их полными именами»?

В конечном счете, важной частью является то, что хранится в dose и resp. Эти переменные используются позже, поэтому мне нужно понять их значения, чтобы я мог сделать что-то похожее в Python (возможно, с numpy, pandas и scipy).

1 Ответ

1 голос
/ 12 ноября 2019

Буквальный R-ответ здесь . Но ваш вопрос, по-видимому, имеет смысл Что такое идиоматический Python-эквивалент R match.call(), и когда я должен / не должен его использовать? , на что ответ:

  • (функция) самоанализ с inspect.signature(f) 1 , 2 : проверить, какие аргументы функции были сопоставлены позиционнымассоциация против ключевого слова / названная ассоциация (против значений по умолчанию). В сигнатуре функции / метода Python func(arg_1, *args, **kwargs) является грубым эквивалентом многоточия R ... в f(args, ...) для передачи неуказанных аргументов (часто наследуемых от super().func()).
    • Никогда не используйте самоанализ в производственном коде
    • Также могут быть проблемы с областями видимости, поскольку область видимости R ведет себя иначе, чем в Python. В общем, в Python не так сложно создать класс (пользовательский подкласс, если вам нужно) и инкапсулировать данные объекта, чтобы избежать проблем).
  • Но почемуВы думаете, что вам вообще нужно переносить строку match.call() на Python? За исключением юнит-тестирования или отладки написанного вами класса, вы обычно не делаете этого на Python. Если вы портируете drc::drm() для своего собственного использования, тогда стандартным советом является внедрение абсолютно минимального интерфейса, необходимого для ваших собственных целей (а не качества релиза, и вам не платят за это) и игнорировать все навороты. Вполне возможно, вам потребуется больше времени, чтобы понять, что делает строка R match.call(), чем игнорировать ее или использовать для вашего варианта использования.
  • Pythonic способ реализации сильно перегруженного прототипа функциипо умолчанию все несущественные параметры равны None, тогда любая логика синтаксического анализа аргументов, чтобы дать им значения «умного по умолчанию» (в зависимости от того, какие другие аргументы были / не были переданы, или от состояния объекта) должна быть удаленавнутри тела функции. Это работает, и пользователи Python должны понимать, что делает ваш получившийся код.

Относительно того, следует ли вам вообще использовать drc в качестве справочного пакета в первую очередь, тот же совет, который я дал ваммесяц назад, пакет drc не имел релиза CRAN с 2016 года, по существу неактивен, имеет только одного или двух сопровождающих, без списка рассылки и не очень хорошо документирован . Вполне могут быть и другие пакеты R с лучшим кодом или лучшей документацией для использования в качестве ссылки. Я едва могу произнести «биоанализ», поэтому предлагаю вам обратиться к соответствующим спискам / группам пользователей (как Python, так и R, академическим и коммерческим) за рекомендациями, с какого справочного пакета начинать.

(Очевидно, если вы действительноВы можете предложить R doc и юнит-тесты сопровождающим drm, а также сделать порт Python, который вы могли бы предложить, но это звучит слишком печально, если вам нужен только базовый эквивалент Python.)

(Этот вопрос вашего вопроса очень широк. Я также попытался обратиться к вашему второму гораздо более конкретному, повторно указав с комментарием. Я не знаю, заменяет ли это это, пожалуйста, обновите его с помощью правок / комментариев.)

...