我有一个像这样的公式列表:
ATi<-list(quote(-(1/(C1 * Rf) + (1/(C1 * Rc) + (1/(C1 * Rint) + 1/(C1 * Rei))))),
quote(1/(C1 * Rei)), 0, quote(1/(C1 * Rint)), quote(1/(C1 * Rf)),
quote(1/(C1 * Rc)), 0, 0)
List of 8
$ : language -(1/(C1 * Rf) + (1/(C1 * Rc) + (1/(C1 * Rint) + 1/(C1 * Rei))))
$ : language 1/(C1 * Rei)
$ : num 0
$ : language 1/(C1 * Rint)
$ : language 1/(C1 * Rf)
$ : language 1/(C1 * Rc)
$ : num 0
$ : num 0
我想在插入其他列表中的每个参数的值后评估每个公式。作为输出,我想要一个结果列表。 我尝试了不同的方法,但我确实找到了解决方案。我有几个,我想要自动化这个过程的智能解决方案。
首先我插入参数的值。 ATi是我的列表名称,value是存储参数值和名称的列表。
value<-c( 0.110546010137993, 9.95953827321208, 7.1751380374394, 285.658095052437,
285.967649817749)
names(value)<-c( "C1", "Rc", "Rei", "Rf", "Rint")
ATi<-gsub("C1",value[["C1"]],ATi)
ATi<-gsub("Rf",value[["Rf"]],ATi)
ATi<-gsub("Rc",value[["Rc"]],ATi)
ATi<-gsub("Rint",value[["Rint"]],ATi)
ATi<-gsub("Rei",value[["Rei"]],ATi)
结果看起来不错但现在我有一个字符列表,我需要一个表达式来进行评估。所以我使用解析。
ATi<-parse(text=ATi)
ATi<-eval(ATi)
结果为0表示不正确。我期待一个8个数字的列表,只有3个0。 我认为错误是在解析时因为apply parse的结果是:
structure(expression(-(1/(0.110546010137993 * 285.658095052437) +
(1/(0.110546010137993 * 9.95953827321208) + (1/(0.110546010137993 * 285.967649817749)
+ 1/(0.110546010137993 * 7.1751380374394)))),
1/(0.110546010137993 * 7.1751380374394), 0, 1/(0.110546010137993 * 285.967649817749),
1/(0.110546010137993 * 285.658095052437), 1/(0.110546010137993 * 9.95953827321208),
0, 0),
srcfile = <environment>, wholeSrcref = structure(c(1L, 0L, 9L, 0L, 0L, 0L, 1L, 9L),
srcfile = <environment>, class = "srcref"))
似乎我只有一个表达式,而不是8,所以我有一个结果。
我也尝试单独评估每个公式,在这种情况下我有不同的错误。 对于第一个公式,我使用上面的代码没有问题。 对于第二个,Parse不起作用,因为他不喜欢“/”。
第二个公式是:
a<-quote(1/(C1 * Rei))
a<-gsub("C1",value[["C1"]],a)
a<-gsub("Rei",value[["Rei"]],a)
使用gsub后看起来有线
c("/", "1", "(0.110546010137993 * 7.1751380374394)")
因此,当我申请解析时......
a<-parse(text=a)
Error in base::parse(...) : <text>:1:1: unexpected '/'
1: /
^
任何想法都将受到赞赏。感谢
答案 0 :(得分:2)
gsub
用于字符串,不适用于language
个对象。 (并注意formula
是R
中的对象类(不是您在此处拥有的)
如果要在给定一组参数的情况下计算值(结果),请使用eval
。
如果要替换值并返回语言对象,则需要do.call
,substitute
,一些技巧
# a smaller example
l <- list(quote(-(1/(C1 * Rf) + (1/(C1 * Rc) + (1/(C1 * Ree) + 1/(C1 * Rei)))))
,quote(1/(C1 * Rei)), 0)
ATi <- list(C1 = 0.11054601,
Ra = 0.04522716,
Rc = 9.95953827,
Ree = 1.65135221,
Rei = 7.17513804,
Rf = 285.65809505)
# to find result use eval
sapply(l, eval, env= ATi)
# [1] -7.678626 1.260743 0.000000
# to substitute values for symbols
lapply(l, function(x) eval(do.call('substitute',list(enquote(x), env = ATi))))
str(res)
# List of 3
# $ : language -(1/(0.11054601 * 285.65809505) + (1/(0.11054601 * 9.95953827) + (1/(0.11054601 * 1.65135221) + 1/(0.11054601 * ...
# $ : language 1/(0.11054601 * 7.17513804)
# $ : num 0
答案 1 :(得分:1)
这个怎么样?我认为只需将您的value
变量从数字更改为列表,就可以使用mnel的sapply解决方案。
ATi<-list(quote(-(1/(C1 * Rf) + (1/(C1 * Rc) + (1/(C1 * Rint) + 1/(C1 * Rei))))),
quote(1/(C1 * Rei)), 0, quote(1/(C1 * Rint)), quote(1/(C1 * Rf)),
quote(1/(C1 * Rc)), 0, 0)
value<-c( 0.110546010137993, 9.95953827321208, 7.1751380374394, 285.658095052437,
285.967649817749)
names(value)<-c( "C1", "Rc", "Rei", "Rf", "Rint")
valuelist <- as.list(value)
sapply(ATi,eval,env=valuelist)
[1] -2.23231928 1.26074329 0.00000000 0.03163297 0.03166725 0.90827576 0.00000000 0.00000000