2013-06-30 3 views
7

Я хочу создать функцию-оболочку, заменяющую некоторые аргументы по умолчанию.R: использование аргумента с многоточием (...)

Здесь суть проблемы я борюсь с:

Error in localWindow(xlim, ylim, log, asp, ...) : 
    formal argument "cex" matched by multiple actual arguments 

Теперь немного контекста. Предположим, что я определить функцию-обертку для сюжета, как это:

myplot <- function(x, ...) { 
    plot(x, cex= 1.5, ...) 
} 

Если я позвоню myplot(1:10, cex= 2) я получаю вышеуказанную ошибку. Я знаю, что могу превратить ... в список

l <- list(...) 

и тогда я мог бы сделать

if(is.null(l[["cex"]])) l[["cex"]] <- 2 

Однако, как я могу «вставить» этот список обратно в многоточие аргумент? Нечто подобное (я знаю, что это не будет работать):

... <- l 

EDIT: Я мог бы использовать по умолчанию в myplot определения (как это было предложено в ответ от @Thomas), но я не хочу: интерфейс функции будет загромождать. Я предполагаю, что я мог определить, вспомогательную функцию, как это:

.myfunchelper <- function(x, cex= 2.0, ...) { 
    plot(x, cex= cex, ...) 
} 

myfunc <- function(x, ...) { 
    .myfunchelper(x, ...) 
} 

Но (я) она менее изящна и (б) не удовлетворяет мое любопытство.

ответ

11

Фактический ОТВЕТ:

Вы можете сделать это через немного обману. Сначала определите свою функцию как прежде, но включите в нее список с аргументами по умолчанию внутри функции. Затем вы можете проанализировать все аргументы с помощью ... в виде списка, заменить значения по умолчанию на что-либо в ..., а затем передать обновленный список аргументов через do.call.

myplot <- function(x, ...) { 
    args1 <- list(cex=4, main="Default Title") # specify defaults here 
    inargs <- list(...) 
    args1[names(inargs)] <- inargs 
    do.call(plot, c(list(x=x), args1)) 
} 

myplot(x=1:3) # call with default arguments 
myplot(x=1:3, cex=2, main="Replacement", xlab="Test xlab") # call with optional arguments 

РАНЬШЕ КОММЕНТАРИЙ:

Проблема здесь можно увидеть через несколько примеров функций:

myplot1 <- function(x, ...) { 
    plot(x, cex= 1.5, ...) 
} 

myplot2 <- function(x, cex=3, ...) { 
    plot(x, cex=cex, ...) 
} 

myplot3 <- function(x, ...) { 
    plot(x, ...) 
} 

myplot1(1:3, cex=3) # spits your error 
myplot2(1:3, cex=3) # works fine 
myplot3(1:3, cex=3) # works fine 

В myplot2, необходимо указать значение по умолчанию cex, но может изменить его. В myplot3, cex просто проходит. Если запустить myplot2 с двумя cex аргументами, вы увидите, что происходит с вашей функцией (myplot1):

myplot2(1:3, cex=3, cex=1.5) # same error as above 

Итак, вы, вероятно, лучше не устанавливать какие-либо значения по умолчанию в plot(), так, то вы можете передать что-нибудь через ... в myplot.

+0

Да, но это именно то, чего я хочу избежать. Реальная проблема сложна, и я не хочу помещать значения по умолчанию в определение вызова функции - уже существует слишком много аргументов. – January

+0

Я обновил данные на основе ответов: http://stackoverflow.com/questions/7028385/can-i-remove-an-element-in-dot-dot-dot-and-pass-it-on/7028786# 7028786 – Thomas

Смежные вопросы