Как получить содержимое... как список вызовов?

86
5

Если я хочу посмотреть, какое выражение передано в функцию, я могу получить его с помощью substitute.


f <- function(x)
{
substitute(x)
}

f(sin(pi))
## sin(pi)


(f возвращает объект класса call. substitute обычно объединяется с deparse, чтобы превратить его в вектор символа, но меня здесь не интересует.)


Я хочу повторить это с аргументами в .... Эта попытка возвращает только первый аргумент:


g <- function(...)
{
substitute(...)
}

g(sin(pi), cos(pi / 2))
## sin(pi)


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


h <- function(...)
{
lapply(..., subsitute)
}

h(sin(pi), cos(pi / 2))
## Error in match.fun(FUN) :
## 'cos(pi/2)' is not a function, character or symbol


Эта попытка вызывает другую ошибку:


i <- function(...)
{
lapply(list(...), substitute)
}

i(sin(pi), cos(pi / 2))

## Error in lapply(list(...), substitute) :
## '...' used in an incorrect context


Как получить выражения, которые я передал в ...?

спросил(а) 2014-04-24T15:58:00+04:00 6 лет, 3 месяца назад
1
Решение
77

если вы хотите сохранить объекты вызова класса:


i <- function(...)
{
l <- match.call()
l <- as.list(l)
l <- l[-1]
l
}

i <- function(...)
{
l <- match.call()
l[[1]] <- as.name("expression")
l
}
i(sin(pi), cos(pi/2))

Или, может быть, вам просто нужен match.call в зависимости от того, что вы хотите делать.
HTH

ответил(а) 2014-04-24T16:10:00+04:00 6 лет, 3 месяца назад
55

Попробуйте следующее:


substitute_multi <- function(...) {
f <- function(e1, ...) {
if (missing(e1)) return(NULL)
else return(list(substitute(e1), substitute_multi(...)))
}
unlist(f(...))
}

Что дает, например:

substitute_multi(x, g(y), 1+2+3)
## [[1]]
## x
##
## [[2]]
## g(y)
##
## [[3]]
## 1 + 2 + 3

Вы также можете вызвать as.expression в результате, чтобы получить объект expression.


IMHO, это решение не так элегантно, как другое, но дает некоторое представление о том, как ... имеет дело с аргументами функции.:)

ответил(а) 2014-04-24T16:10:00+04:00 6 лет, 3 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема