使用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
    中,其中
    P1c
    为2,
    因此:
    +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)

我的方法包括将所有内容转换为字符串,为这些字符串指定数值,根据变量是否在select列中过滤数据,然后将这些列相乘,然后转换为公式

#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
将其作为单独的脚本加载和处理。另一个明智的方法是编程或使用一些计算器库,这些库可以解释某种类型的字节码磁带,并将输入转换成这样的磁带。然后,每次调用导数函数都会使用磁带和输入调用计算器机器,并将计算器的输出复制到导数向量中。