Есть количество хороших (1 2 3) StackOverflow вопросы об использовании многоточия («точки») в R. Тем не менее, я еще не встречал ни одной, которая относилась бы к моему конкретному варианту использования. Я изо всех сил пытаюсь написать оболочку совместимости для функции, которая изменяет имя аргумента с исходного вызова функции на вызов базовой функции. Например, можно вызвать newMean(c(1:10,1000,NA),.2,rmNA=TRUE)
, а не mean(c(1:10,1000,NA),.2,na.rm=TRUE)
. Мы могли бы даже захотеть написать нашу оболочку таким образом, чтобы мы не уничтожали вызовы S3 для mean, предполагая, что все вызовы newMean предназначены для отправки для mean.default. Очевидный путь вперед выглядит примерно так (в псевдокоде):
newMean <- function(x,...) {
dots <- list(...)
names(dots)[names(dots)=="rmNA"] <- "na.rm"
x.list <- list(x=x)
dots <- c(x.list,dots)
do.call(base::mean,dots)
}
Это оставляет нам значение в точках вроде:
dots <- structure(list(x = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1000, NA),
0.2, na.rm = TRUE), .Names = c("x", "", "na.rm"))
Все идет нормально. Но что-то не так, как я мог бы ожидать. Рассмотрим команду newMean(c(1:10,1000,NA),.2,TRUE)
по сравнению с base::mean(c(1:10,1000,NA),.2,TRUE)
. Когда мы вызываем base::mean
, R вызывает mean.default, потому что getS3method("base::mean",class(x))
для x в вызове является числовым и не имеет совпадений. match.call(mean.default)
, вызываемый при отладке newMean
показывает, что (безымянный) второй и третий аргументы, конечно, назначаются в порядке трем аргументам перед многоточием в mean.default. Напротив, do.call, похоже, игнорирует безымянные аргументы (может быть, рассматривает их как часть многоточия в вызове mean.default?).
Я попытался определить используемый метод S3 с помощью getS3method
, а затем с помощью formals
, чтобы вникнуть и определить количество формальных аргументов для конкретного отправляемого метода S3, но мне не удалось сгенерировать способ вызова mean :: base, который гибко учитывает количество формальных элементов, присутствующих в вызываемом методе, и соответствующим образом сопоставляет их.
Есть ли способ исправить поведение newMean таким образом, чтобы trim и na.rm соответствовали соответствующим образом, без удаления сопоставленного вызова из newMean в base: mean (например, deparse(match.call(base::mean))
) и вручную подстановки имен аргументов? Причина, по которой я не хочу, чтобы строка манипулировала подстановкой имен аргументов, заключается в том, что я могу представить себе случаи (за пределами этого игрушечного примера), когда значения в вызове могут быть частично сопоставлены с именами аргументов.
match.arg
допускает частичные совпадения. (Я также обнаружил, что использование слова «эллипсы» сбивает с толку, поскольку считаю, что правильным термином для обозначения трех точек вместе является просто многоточие.) - person IRTFM   schedule 27.11.2013newMean(c(1:10,1000,NA), trim=.2, rmNA=TRUE)
, вы сможете использоватьmatch.args
. - person IRTFM   schedule 27.11.2013