使用dplyr和条件格式从字符串构造常微分方程
我试图创建一个特定变量的方程组,使用字符串数据帧中的使用dplyr和条件格式从字符串构造常微分方程,r,dplyr,apply,ode,mutate,R,Dplyr,Apply,Ode,Mutate,我试图创建一个特定变量的方程组,使用字符串数据帧中的dplyr和prod,用于R中的常微分解算器(deSolve)。变量的位置决定了方程的形式,因此我使用grep,filter\u at,mutate\u at,以及apply 构建方程式取决于基于以下内容的感兴趣字符串/变量列 一, 如果发现变量为产品(P1、P2、P3),则乘以:+1*Rate*R1c*R1*R2c*R2*R3c*R3*(P1c或P2c或P3c) 我试图用最后一个术语(P1c或P2c或P3c)传达的是,取决于变量(P1、P2
dplyr
和prod
,用于R中的常微分解算器(deSolve
)。变量的位置决定了方程的形式,因此我使用grep
,filter\u at
,mutate\u at
,以及apply
构建方程式取决于基于以下内容的感兴趣字符串/变量列
一,
- 如果发现变量为产品
,则乘以:(P1、P2、P3)
+1*Rate*R1c*R1*R2c*R2*R3c*R3*(P1c或P2c或P3c)
- 我试图用最后一个术语
传达的是,取决于变量(P1c或P2c或P3c)
的位置,然后 需要乘以相应的(P1、P2或P3)
,但不是全部 其中(P1c、P2c或P3c)
- 如果发现变量为反应物
,则 乘法(R1、R2、R3)
-1*速率*R1c*R1*R2c*R2*R3c*R3
- 然后我想把所有的东西加在一起,把它设为“dVariable”
dVariable=Sum(所有产物表达式)+Sum(所有反应物表达式)
structure(list(
Reaction = c("k3", "k4", "k40", "k38", "k39", "k44"),
Rate = c("kHV_H2O2", "kHV_HO2-", "3", "27000000", "5500000000", "6600000000"),
R1c = c(1, 1, 1, 1, 2, 1),
R1 = c("H2O2", "HO2-", "HO2$", "$OH", "$OH", "$OH"),
R2c = c(NA, NA, 1, 1, NA, 1),
R2 = c(NA, NA, "H2O2", "H2O2", NA, "HO2$"),
R3c = c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_),
R3 = c(NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_),
P1c = c(2, 1, 1, 1, 1, 1),
P1 = c("$OH", "$OH", "O2", "HO2$", "H2O2", "O2"),
P2c = c(NA, 1, 1, 1, NA, 1),
P2 = c(NA, "O$-", "$OH", "H2O", NA, "H2O"),
P3c = c(NA, NA, 1, NA, NA, NA),
P3 = c(NA, NA, "H2O", NA, NA, NA)),
row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))
如果我们把OH看作是感兴趣的物种,那么:
- 在第1行
首先作为产品出现在$OH
中,其中P1
为2,P1c
因此:+1*(kHV_H2O2)*(1)*(H2O2)*(2)
- 在第4行中,$OH首先作为
反应物在
,因此R1
-1*(27000000)*($OH)*(1)*(H2O2)*(1)
- 最后,将这两个变量合并为一个新变量
d$OH=+1*(kHV_H2O2)*(1)*(H2O2)*(2)-1*(27000000)*($OH)*(1)*(H2O2)*(1)
#Set the Reaction variable equal to the Rate Constant.
for (i in seq(nrow(df2))) assign(df2$Reaction[i],df2$Rate[i])
#Drop Rate from main data frame
df2 <- df2 %>% mutate(Rate= NULL)
#Find the unique chemical species
# Drop all numbers and constnats
Species <- df2 %>% mutate(
Rate = NULL, R1c = NULL, R2c = NULL, R3c = NULL, P1c = NULL, P2c = NULL, P3c = NULL, Reaction = NULL)
#Uniques
Species <- unique(as.data.frame(c(as.matrix(Species))), drop = FALSE)
names(Species) <- "Species"
# Omit N/A and unknowns
Species <- filter(Species, Species != "unknown")
Species <- na.omit(Species)
# create new variable for each unique species for deltatime Step
Species <- Species %>% mutate(
DeltaSpecies = paste0("d", as.character(Species),sep=""))
#Multiply Each Equation
nms <- grep("^R|^Reaction$|c$", names(df2), value = TRUE)
nms2 <- grep("^R|^Reaction$", names(df2), value = TRUE)
Prod <- function(x) paste(sub("^(.*[[:punct:]].*)", "`\\1`", na.omit(x)), collapse = "*") # if the string contains, begins, ends with a $,-,+ then put it in ' '
#Match Products and Reactants
Products <- df2 %>% filter_at(vars(P1,P2,P3,P1c,P2c,P3c), any_vars(. %in% as.character(Species$Species[[16]])))
Reactants <- df2 %>% filter_at(vars(R1,R2,R3,R1c,R2c,R3c), any_vars(. %in% as.character(Species$Species[[16]])))
Reactants_final <- paste(apply(Reactants[nms2], 1, Prod), collapse = " - ")
Products_final <- paste(apply(Products[nms], 1, Prod), collapse = " + ")
Combine <- paste(Products_final, Reactants_final, sep = " - ")
Formula <- as.formula(paste(Species$DeltaSpecies[[16]], Combine, sep = " ~ "))
#将反应变量设置为速率常数。
对于(序列中的i(nrow(df2)))分配(df2$反应[i],df2$速率[i])
#从主数据帧的丢弃率
df2%突变(速率=空)
#寻找独特的化学物种
#删除所有数字和常量
物种%变异(
速率=零、R1c=零、R2c=零、R3c=零、P1c=零、P2c=零、P3c=零、反应=零)
#独特的
基础反应速度计算中的物种,是否应为基础水平=速率*R1^R1c*R2^R2c*R3^R3c
?然后,当你将其分配给物质的微分增量时,R1
,它得到多重性作为-R1c*base\u-vel
的一个因子,对于这个反应的产物P1
,它与它的多重性相乘,+P1c*base\u-vel
,不完全一样。base\u-vel
将是Rate*R1^R1c*R2^R2c*R3^R3c
,然后如果变量在R1、R2或R3
中,我们乘以-1*base\u-vel
,如果它是一个乘积,我们将其乘以(+P1c、P2c、P3c)*base\u-vel
,这取决于变量是在P1、P2还是P3
中,最大的问题是如何将所有单个字符串转换成一个有用的表达式,以便在ODE解算器中使用。我的方法涉及到#df2$反应,一种方法是进行完整的代码翻译,也就是说,您的输出是系统作为代码的导数函数。然后,R
将其作为单独的脚本加载和处理。另一个明智的方法是编程或使用一些计算器库,这些库可以解释某种类型的字节码磁带,并将输入转换成这样的磁带。然后,每次调用导数函数都会使用磁带和输入调用计算器机器,并将计算器的输出复制到导数向量中。