Перебирать символы, определенные в некоторой внутренней среде, используя нестандартную оценку
Я хотел бы сделать ниже работы программы.
Я знаю, ошибка заключается в list(f1, f2)
, но я не нашел способа заставить это работать до сих пор. Проблема в том, что f1
а также f2
снаружи не известны func
среда, но я хотел бы просто передать их как имя / символ...
x = 1:2
func = function(f,x){
f1 = function(x)
sum(x)
f2 = function(x)
prod(x)
eval(substitute(f))(x)
}
func(f1, x) # works
func(f2, x) # works
sapply(list(f1,f2), function(f) func(f,x)) # cannot iterate over f's
3 ответа
С этим определением f
может быть символьной строкой с именем функции или неоцененным выражением с именем функции.
func <- function(f, x) {
funs <- list(f1 = sum, f2 = prod)
ch <- deparse(substitute(f))
if (! ch %in% names(funs)) ch <- as.name(f)
funs[[ch]](x)
}
func(f1, 1:2)
## [1] 3
func("f1", 1:2)
## [1] 3
sapply(c("f1", "f2"), func, x = 1:2)
## f1 f2
## 3 2
sapply(c(quote(f1), quote(f2)), func, x = 1:2)
## [1] 3 2
sapply(expression(f1, f2), func, x = 1:2)
## [1] 3 2
В комментарии к этому вопросу автор упомянул, что в конце концов они не могут использовать недооцененные выражения. Если используются только символьные строки, то это можно упростить до этого:
func2 <- function(f, x) {
funs <- list(f1 = sum, f2 = prod)
funs[[f]](x)
}
func2("f1", 1:2)
## [1] 3
sapply(c("f1", "f2"), func2, x = 1:2)
## f1 f2
## 3 2
Обновления
Исправления и улучшения.
Я не знаю, как бы вы сделали это с NSE, но вы можете просто использовать get
вместо substitute
, Это кажется мне более аккуратным, так как вы можете использовать строки, чтобы более легко называть выходы
x = 1:2
func = function(f,x){
f1 = function(x)
sum(x)
f2 = function(x)
prod(x)
eval(get(f))(x)
}
func("f1", x)
func("f2", x)
sapply(list("f1", "f2"), function(f) func(f,x))
Хорошо, нашел решение, но я думаю, что это можно сделать несколько красивее...
x = 1:2
func = function(f,x){
f1 = function(x)
sum(x)
f2 = function(x)
prod(x)
eval(f)(x)
}
sapply(list(substitute(f1),substitute(f2)), function(f) func(f,x)) # can now iterate over f's