Create New Columns using several lists as input

Hello All,

I'm currently working with output data from a chemical box model and I'm trying to calcualte rate reactions using the models ouput of concentration and rate constants. I want to create a dataframe that adds columns for each reaction that I specify. I'm using a few lists as input to make the reactions, and using for loops to loop through all of the list (for whatever reason, map and lapply don't quite do what I want them to). I
The formula I'm using is

Reaction Rate = SpeciesXSpeciesYRateConstant*Fraction
Where a species could be something like "CH3CO3", Rate Reaction could be K1.

The data and code I'm using are

MainData<-tibble(
  CH3CO3 = c(22,3,6,7.1),
  HO2=c(545,2.1,9,4),
  C3H6=c(33,22.4,1,6),
  K1=c(33,21,5,3.5),
  K2=c(3,12,6,3.7),
  K3=c(2,5,22,6)
)

R1<-c("CH3CO3", "HO2", "C3H6")
R2<-c("HO2", "C3H6", "CH3CO3")
KRate<-c("K1", "K2", "K3")
Frac<-c(0.22,0.5, 1)

Testfun<-function(df, R1,R2,Frac,KRate){

  for (x in R1){
    for(y in R2){
      for(f in Frac){
        for(K in KRate){
          Conc2<-df%>%
            mutate("{x}+{y}" := 2.5e13*df[[x]]*df[[y]]*df[[K]]*f)
          
        }
      }
    }
  }
  return(Conc2)
}


TestOutput<-Testfun(MainData, R1,R2,Frac,KRate)


This gets me pretty close, but instead of creating new columns, it makes 1 column and then overwrites it.
It's important to note the order of of the input lists are important. I want the 1st element of each list to multipl y with each other, and the second element of the list to multply with each other and so on.

I had an idea:

library(tidyverse)
library(glue)
library(rlang)

(MainData <- tibble(
  CH3CO3 = c(22, 3, 6, 7.1),
  HO2 = c(545, 2.1, 9, 4),
  C3H6 = c(33, 22.4, 1, 6),
  K1 = c(33, 21, 5, 3.5),
  K2 = c(3, 12, 6, 3.7),
  K3 = c(2, 5, 22, 6)
)%>% mutate(jn = 1L))

(calc_data <-   expand_grid(
  R1 = c("CH3CO3", "HO2", "C3H6"),
  R2 = c("HO2", "C3H6", "CH3CO3"),
  Frac = c(0.22, 0.5, 1), 
  KRate = c("K1", "K2", "K3")
) %>%
  mutate(jn = 1L))

left_join(
  MainData ,
  calc_data
) %>%
  rowwise() %>%
  mutate(
    formula_to_use = glue("2.5e13*{R1}*{R2}*{KRate}*{Frac}"),
    result = eval(parse_expr(formula_to_use))
  )

I'm managed to figure out how to get this working properly. It seems rather than 4 nested for loops, 1 for loop indexing over each list works instead. This keeps the order of the reactions and doesn't create reactions I don't need.

Testfun<-function(df, R1, R2, Frac, KRate){
  print(df)
  for (i in 1:length(R1)){
          df[[paste0(R1[[i]],"+",R2[[i]])]]<-2.5e13*df[[R1[[i]]]]*df[[R2[[i]]]]*df[[KRate[[i]]]]*Frac[[i]]
  }
  return(df)
}

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.