关于重命名函数的问题
Issue on renaming functions
我正在编写一些代码来计算函数的导数。我设法为 1 个变量生成一阶和二阶导数并将其作为函数存储在环境中,以便稍后绘制它们。现在我正在尝试计算具有 2 个或更多变量的方程的偏导数,但我找不到可以在环境中生成与函数的偏导数一样多的函数的代码。
澄清一下,对于我使用的 1 个变量:
f <- function(x) cos(20*x)*exp(-1*x)
F.<- function (x) eval(D(as.expression(body(f)), "x"))
F..<- function (x) eval(D(as.expression(D(as.expression(body(f)), "x")),"x"))
它运行完美,我在环境中获得了 3 个函数:
但是对于超过 1 个变量,我必须遍历这个函数并生成与方程的偏导数一样多的函数。
我的问题是:如何生成一个循环来计算函数的偏导数并将它们存储为函数,每个函数都有一个自定义名称?
我在 for 循环中尝试了导数函数,但无法为每次导数计算定义不同的名称:
for (i in 1:nro_variables) {
var_D = vector_variables[i]
F.<- function (x) eval(D(as.expression(body(f)), var_D))
}
eval
和parse
可以用来定义函数,assign
可以给它正确的名字。
f <- function(x) 2 * x
g <- function(x, y) x * y
h <- function(x, y, z) x * y + z
fns <- c("f", "g", "h")
for (fn in fns) {
for (variable in formalArgs(fn)) {
function_name <- glue::glue("{toupper(fn)}.{variable}")
fn_definition <- eval(parse(text = glue::glue("function({paste0(formalArgs(fn), collapse = ',')}) eval(D(as.expression(body({fn})), '{variable}'))")))
assign(
function_name,
fn_definition
)
}
}
ls.str(mode = "function")
#> f : function (x)
#> F.x : function (x)
#> fn_definition : function (x, y, z)
#> g : function (x, y)
#> G.x : function (x, y)
#> G.y : function (x, y)
#> h : function (x, y, z)
#> H.x : function (x, y, z)
#> H.y : function (x, y, z)
#> H.z : function (x, y, z)
类似于避免使用分配许多单独的相似对象来淹没您的全局环境,考虑使用可以索引元素的单个列表以获得更好的串行组织。请参阅@GregorThomas 的最佳实践 answer 提倡:
Don't ever create d1
d2
d3
, ..., dn
in the first place. Create a list d
with n
elements.
具体来说,如果 vector_variables
是字符向量,使用 simplify=FALSE
的 sapply
将 return 命名函数列表。是的,仍然可以调用列表中的函数。
partial_deriv_funcs <- sapply(vector_variables, function(var_D) {
f <- function(x) cos(20*x)*exp(-1*x)
return(function(x) eval(D(as.expression(body(f)), var_D)))
}, simplify = FALSE)
单独或迭代调用函数元素:
# CALL SINGLE FUNCTION WITH SINGLE PARAM
result <- partial_deriv_funcs[['var1']](param)
# CALL SAME FUNCTION WITH VECTOR OF PARAMS
results <- lapply(param_vector, partial_deriv_funcs[['var1']])
# CALL ALL FUNCTIONS USING SAME PARAM
results <- lapply(partial_deriv_funcs, function(f) f(param))
# CALL ALL FUNCTIONS EACH WITH DIFFERENT PARAM
results <- mapply(function(f,p) f(p), partial_deriv_funcs, param_per_func_vector, SIMPLIFY= FALSE)
results <- Map(function(f,p) f(p), partial_deriv_funcs, param_per_func_vector) # EQUIVALENT
我正在编写一些代码来计算函数的导数。我设法为 1 个变量生成一阶和二阶导数并将其作为函数存储在环境中,以便稍后绘制它们。现在我正在尝试计算具有 2 个或更多变量的方程的偏导数,但我找不到可以在环境中生成与函数的偏导数一样多的函数的代码。
澄清一下,对于我使用的 1 个变量:
f <- function(x) cos(20*x)*exp(-1*x)
F.<- function (x) eval(D(as.expression(body(f)), "x"))
F..<- function (x) eval(D(as.expression(D(as.expression(body(f)), "x")),"x"))
它运行完美,我在环境中获得了 3 个函数:
但是对于超过 1 个变量,我必须遍历这个函数并生成与方程的偏导数一样多的函数。
我的问题是:如何生成一个循环来计算函数的偏导数并将它们存储为函数,每个函数都有一个自定义名称?
我在 for 循环中尝试了导数函数,但无法为每次导数计算定义不同的名称:
for (i in 1:nro_variables) {
var_D = vector_variables[i]
F.<- function (x) eval(D(as.expression(body(f)), var_D))
}
eval
和parse
可以用来定义函数,assign
可以给它正确的名字。
f <- function(x) 2 * x
g <- function(x, y) x * y
h <- function(x, y, z) x * y + z
fns <- c("f", "g", "h")
for (fn in fns) {
for (variable in formalArgs(fn)) {
function_name <- glue::glue("{toupper(fn)}.{variable}")
fn_definition <- eval(parse(text = glue::glue("function({paste0(formalArgs(fn), collapse = ',')}) eval(D(as.expression(body({fn})), '{variable}'))")))
assign(
function_name,
fn_definition
)
}
}
ls.str(mode = "function")
#> f : function (x)
#> F.x : function (x)
#> fn_definition : function (x, y, z)
#> g : function (x, y)
#> G.x : function (x, y)
#> G.y : function (x, y)
#> h : function (x, y, z)
#> H.x : function (x, y, z)
#> H.y : function (x, y, z)
#> H.z : function (x, y, z)
类似于避免使用分配许多单独的相似对象来淹没您的全局环境,考虑使用可以索引元素的单个列表以获得更好的串行组织。请参阅@GregorThomas 的最佳实践 answer 提倡:
Don't ever create
d1
d2
d3
, ...,dn
in the first place. Create a listd
withn
elements.
具体来说,如果 vector_variables
是字符向量,使用 simplify=FALSE
的 sapply
将 return 命名函数列表。是的,仍然可以调用列表中的函数。
partial_deriv_funcs <- sapply(vector_variables, function(var_D) {
f <- function(x) cos(20*x)*exp(-1*x)
return(function(x) eval(D(as.expression(body(f)), var_D)))
}, simplify = FALSE)
单独或迭代调用函数元素:
# CALL SINGLE FUNCTION WITH SINGLE PARAM
result <- partial_deriv_funcs[['var1']](param)
# CALL SAME FUNCTION WITH VECTOR OF PARAMS
results <- lapply(param_vector, partial_deriv_funcs[['var1']])
# CALL ALL FUNCTIONS USING SAME PARAM
results <- lapply(partial_deriv_funcs, function(f) f(param))
# CALL ALL FUNCTIONS EACH WITH DIFFERENT PARAM
results <- mapply(function(f,p) f(p), partial_deriv_funcs, param_per_func_vector, SIMPLIFY= FALSE)
results <- Map(function(f,p) f(p), partial_deriv_funcs, param_per_func_vector) # EQUIVALENT