予期しないエッジケースがあると思いますが、次のようにすることができます:
chunk1a <- 'a + b^2/c'
chunk1b <- '4 * c - a^a'
chunk1 <- paste('(', chunk1a, ')^2 +', chunk1b, '* 4')
eval
parse
それからあなたは常に恐ろしい土地に入ります:
a <- 1
b <- 2
c <- 3
eval(parse(text=chunk1))
# [1] 13.44444
deriv
なしでドロップすることもできますeval
:
deriv(parse(text=chunk1), c('a', 'b', 'c'))
# expression({
# .expr1 <- b^2
# .expr3 <- a + .expr1/c
# .expr7 <- a^a
# .value <- .expr3^2 + 4 * c - .expr7 * 4
# .grad <- array(0, c(length(.value), 3L), list(NULL, c("a",
# "b", "c")))
# .grad[, "a"] <- 2 * .expr3 - (a^(a - 1) * a + .expr7 * log(a)) *
# 4
# .grad[, "b"] <- 2 * (2 * b/c * .expr3)
# .grad[, "c"] <- 4 - 2 * (.expr1/c^2 * .expr3)
# attr(.value, "gradient") <- .grad
# .value
# })
面倒な作業を行う関数を作成することもできます。
myfun <- function(expr_string1, wrapper1=NULL, expr_string2=NULL, wrapper2=NULL, join_fun=NULL) {
if (!is.null(wrapper1)) {
expr_string1 <- paste('(', expr_string1, ')', wrapper1)
}
if (!is.null(wrapper2)) {
expr_string2 <- paste('(', expr_string2, ')', wrapper2)
}
if (!is.null(expr_string2) & !is.null(join_fun)) {
expr_string1 <- paste(expr_string1, join_fun, expr_string2)
}
return (expr_string1)
}
そしてそれを呼び出します:
deriv(parse(text=myfun(chunk1a, '^2', chunk1b, '*4', '+')),
c('a', 'b', 'c'))
うん…