"Формальный аргумент" foo "соответствует нескольким аргументам" - как справиться с этим в R?

Иногда вызов функции с определенными аргументами приводит к сообщению об ошибке formal argument "foo" matched by multiple actual arguments. Можно ли распечатать список двусмысленных фактических аргументов?

Причина, по которой я спрашиваю об этом, в настоящее время является проблемой с функцией plot для объектов класса mixEM (сгенерированных normalmixEM из пакета mixtools). Он не принимает аргумент ylim, приводящий к ошибке выше, но когда я пытаюсь использовать ylim2 (как он работает для xlab2, main2, col2 и т.д.), Он говорит "ylim2" is not a graphical parameter, Поэтому мне интересно, какие фактические аргументы соответствуют ylim?

Использование formals(plot.mixEM) не помогает, потому что в нем нет ничего, начиная с ylim, но затем в конце он ссылается на ..., которые являются графическими параметрами, переданными в plot. Однако для plot функция ylim была бы однозначной. Получение более точного описания ошибки из R со списком конфликтующих аргументов было бы полезно.

UPD: MWE:

library(mixtools)
wait = faithful$waiting
mixmdl = normalmixEM(wait)
plot(mixmdl, which = 2, xlim = c(25, 110), nclass=20)
lines(density(wait), lty = 2, lwd = 2)

Это вызывает ошибку:

plot(mixmdl, which = 2, xlim = c(25, 110), ylim = c(0, .5), nclass=20)

# Error in hist.default(x, prob = TRUE, main = main2, xlab = xlab2, ylim = c(0, :
# formal argument "ylim" matched by multiple actual arguments`

Это просто не работает:

plot(mixmdl, which = 2, xlim = c(25, 110), ylim2 = c(0, .5), nclass=20)

# Warning messages:
# 1: In title(main = main, sub = sub, xlab = xlab, ylab = ylab, ...) :
#   "ylim2" is not a graphical parameter
# 2: In axis(1, ...) : "ylim2" is not a graphical parameter
# 3: In axis(2, ...) : "ylim2" is not a graphical parameter

Ответ 1

Ваша проблема по существу относится к типу:

plot(1:10, rnorm(10), ylim=c(0,1), ylim=c(-1,100))
Error in plot.default(1:10, rnorm(10), ylim = c(0, 1), ylim = c(-1, 100)) : 
  formal argument "ylim" matched by multiple actual arguments

потому что ваше определение ylim переходит к функции plot с аргументом "..." в следующей строке plot.mixEM:

hist(x, prob = TRUE, main = main2, xlab = xlab2, ylim = c(0, maxy), ...)

в то время как ylim был определен со следующим верхним пределом:

maxy <- max(max(a$density), 0.3989 * mix.object$lambda/mix.object$sigma)

Обратите внимание, что вы вызываете функцию построения графика для объекта типа mixEM. Глядя на код функции построения по умолчанию plot.default, вы будете озадачены, так как на самом деле это plot.mixEM, который вы вызываете. Если вы наберете plot.mixEM в терминале, вы увидите его код, и? Plot.mixEM также поможет вам. Это типичный подход в R, где функция по умолчанию functionname.default заменяется функцией класса, предоставляемой пакетом в формате functionname.classname.

У вас есть несколько вариантов:

  • Напишите свой собственный plot.mixEM, заменив жестко закодированную часть в оригинальной функции, вам нужно только изменить пару линий.
  • Разделите окно перед plot.mixEM и добавьте параметр "add = TRUE", что означает, что мы не создадим новое окно построения, а вместо этого добавим существующий.

Вот как работает вариант 2:

library(mixtools)
wait = faithful$waiting
mixmdl = normalmixEM(wait)
plot.new()
plot.window(xlim=c(25,110), ylim=c(0,0.5))
plot(mixmdl, which = 2, nclass=20, add = TRUE)
lines(density(wait), lty = 2, lwd = 2)
box(); axis(1); axis(2); title(xlab="Data", ylab="Density")

Example plot

Ответ 2

library(mixtools)
wait = faithful$waiting
mixmdl = normalmixEM(wait)

plot(mixmdl, which = 2, xlim = c(25, 110), ylim = c(0, .5), nclass=20)
#Error in hist.default(x, prob = TRUE, main = main2, xlab = xlab2, ylim = c(0,  : 
#  formal argument "ylim" matched by multiple actual arguments

Сообщение об ошибке достаточно информативно. Он сообщает вам, какая функция получает параметр дважды. Для получения дополнительной информации:

traceback()

# 4: hist.default(x, prob = TRUE, main = main2, xlab = xlab2, ylim = c(0, 
#                                                                      maxy), ...)
# 3: hist(x, prob = TRUE, main = main2, xlab = xlab2, ylim = c(0, 
#                                                              maxy), ...)
# 2: plot.mixEM(mixmdl, which = 2, xlim = c(25, 110), ylim = c(0, 
#                                                              0.5), nclass = 20)
# 1: plot(mixmdl, which = 2, xlim = c(25, 110), ylim = c(0, 0.5), 
#         nclass = 20)

Итак, есть вызов hist в plot.mixEM, который уже устанавливает ylim = c(0,maxy). Ваш ylim = c(0,0.5) передается через многоточие (...), так что hist.default передается ylim дважды. Следовательно, ошибка.