Подтвердить что ты не робот

Смутно...()?

В еще один вопрос, sapply(substitute(...()), as.character) использовался внутри функции для получения имен, переданных функции. Часть as.character звучит нормально, но что на самом деле делает ...()?

Недействительный код вне substitute:

> test <- function(...) ...()
> test(T,F)
Error in test(T, F) : could not find function "..."

Еще несколько тестовых примеров:

> test <- function(...) substitute(...())
> test(T,F)
[[1]]
T

[[2]]
F

> test <- function(...) substitute(...)
> test(T,F)
T
4b9b3361

Ответ 1

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

  • Прежде чем выполнять замену на любой из своих компонентов, substitute() сначала анализирует оператор R.

  • ...() анализирует объект вызова, тогда как ... анализирует объект имени.

  • ... - это специальный объект, предназначенный только для использования в вызовах функций. Как следствие, код C, реализующий подстановку, принимает специальные меры для обработки ..., когда он найден в объекте вызова. Подобные меры предосторожности не принимаются, когда ... встречается как символ. (Соответствующий код находится в функциях do_substitute, substitute и substituteList (особенно последние два) в R_SRCDIR/src/main/coerce.c.)

Итак, роль () в ...() состоит в том, чтобы заставить оператор анализироваться как объект вызова (aka language), чтобы подстановка возвращала полностью расширенное значение точек. Может показаться удивительным, что ... заменяется даже тогда, когда он находится снаружи (), но: (a) вызовы хранятся внутри как объекты, подобные спискам, и (b) соответствующий код C, кажется, не делает различий между первым элементом этого списка и последующими.


Просто обратите внимание: для изучения поведения substitute или классов различных объектов мне полезно настроить небольшую песочницу, например:

f <- function(...) browser()
f(a = 4, 77, B = "char")
## Then play around within the browser
class(quote(...))  ## quote() parses without substituting
class(quote(...()))
substitute({...})
substitute(...(..., X, ...))
substitute(2 <- (makes * list(no - sense))(...))