Использование dplyr и условного форматирования для построения обыкновенного дифференциального уравнения из строк - PullRequest
2 голосов
/ 26 сентября 2019

Я пытаюсь создать систему уравнений для конкретной переменной, используя dplyr и prod из строки данных для использования в обычном дифференциальном решателе в R (deSolve).Расположение переменной диктует форму уравнения, и поэтому я использую grep, filter_at, mutate_at и apply.

Построение уравнения зависит от столбца интересующей строки / переменной на основе следующего i.

  • Если переменная когда-либо найдена как произведение (P1,P2,P3), умножьте: +1 * Rate * R1c * R1 * R2c * R2 * R3c * R3 * (P1c or P2c or P3c)

  • Что я пытаюсь передать этимпоследний член (P1c or P2c or P3c) - это то, что в зависимости от того, где переменная (P1,P2 or P3), вам нужно умножить на соответствующие (P1c, P2c, or P3c), но не все из них

  • Если переменная найдена в качестве реагента(R1,R2,R3) затем умножить -1 * Rate * R1c * R1 * R2c * R2 * R3c * R3
  • Затем я хочу сложить все вместе и установить его равным «dVariable»
    1. dVariable = Sum(all product expressions) + Sum(all Reactant expressions)

Ниже приведен пример фрейма данных, который я урезал.

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)

Мой подход заключается в преобразовании всего в строку, присвоении числовых значений этим строкам, фильтрации данныхв зависимости от того, находится ли переменная в столбце выбора, а затем умножить эти столбцы вместе, а затем преобразовать в формулу.

#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 = " ~ "))

Я не понимаю, как условно создать выражение продукта без использования ненужных переменныхприсвоение значений строкам / переменным и извлечение полезной формулы с переменными в форме dX <- a*X + Y*Z для использования в решателе ODE.Я понимаю, что это многословный вопрос, но мне просто интересны советы, чтобы указать мне правильное направление для решения проблемы (включая изучение новых функций).Будет ли eval(parse подходом к проблеме преобразования строк в переменные и присвоения им значений?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...