逐个建立配方

时间:2013-01-30 23:37:53

标签: r

我正在尝试构造一个在deriv()中使用的公式。它很长,所以我想把它分成几部分(每个部分都有子部分),但我不知道该怎么做。我已经尝试了as.formula(),expression(),eval(),paste()等的各种组合,但还没有让它起作用。我希望它最终看起来像这样(非工作示例):

chunk1a <- a + b^2/c
chunk1b <- 4*c - a^2
chunk1 <- chunk1a^2 + 4*chunk1b

chunk2a <- 3*a
chunk2b <- a*b*c^2
chunk2 <- 7*chunk2b/chunk2a

chunk3a <- 5*b*c/a
chunk3b <- b^4 + 5*c
chunk3 <- 4*chunk3a - 1/chunk3b

myderiv <- deriv(~ chunk1 + chunk2/chunk3, 
                 c('a', 'b', 'c'))

3 个答案:

答案 0 :(得分:3)

而不是字符串和字符串操作(比如@ Justin的回答),使用引用的调用和语言操作:

chunk1a <- quote(a + b^2/c)
chunk1b <- quote(4 * c - a^a)

substitute((a) ^ 2 + (b) * 4, list(a = chunk1a, b = chunk1b))

# OR
bquote(.(chunk1a) ^ 2 + .(chunk1b) * 4)

https://github.com/hadley/devtools/wiki/Computing-on-the-language

的更多详情

答案 1 :(得分:1)

我认为会出现无法预料的边缘情况,但你可以这样做:

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'))

...益

答案 2 :(得分:1)

试试这个:

library(Ryacas)

a <- Sym("a")
b <- Sym("b")
c <- Sym("c")

chunk1a <- a + b^2/c
chunk1b <- 4*c - a^2
chunk1 <- chunk1a^2 + 4*chunk1b

chunk2a <- 3*a
chunk2b <- a*b*c^2
chunk2 <- 7*chunk2b/chunk2a

chunk3a <- 5*b*c/a
chunk3b <- b^4 + 5*c
chunk3 <- 4*chunk3a - 1/chunk3b

deriv(deriv(deriv(chunk1 + chunk2/chunk3, a), b), c)